如何将CSV单列的州/城市数据转换为层级列?
解决CSV单列州-城市数据转两列层级结构的问题
我来帮你搞定这个需求!你想要把包含州、城市和NaN的单列数据转换成州与城市一一对应的两列结构,这个用Pandas可以很简洁地实现,先说说你现有代码的问题,再给你正确的解决方案。
你的代码存在的问题
- NaN判断错误:原数据里的空值是
NaN,不是空字符串'',用STATE == ''根本匹配不到这些空行,应该用pd.isna(STATE)来判断。 - 变量与逻辑混乱:代码里的
STATE_df没有定义,而且循环里不管当前行是州还是城市,都直接取STATE_df['citystate'][i]并自增i,完全没有跟踪当前的州,自然无法正确关联州和对应的城市。
正确的实现方法
根据你给出的数据规律(州名全大写,后面跟着NaN,再是城市,最后又以NaN分隔下一个州),我们可以用以下步骤处理:
步骤1:读取并预处理数据
首先读取CSV文件,然后删除所有NaN行,得到清晰的州和城市序列:
import pandas as pd # 读取CSV,假设文件名为data.csv,列名设为citystate df = pd.read_csv('data.csv', header=None, names=['citystate']) # 删除所有包含NaN的行,重置索引 df_clean = df.dropna().reset_index(drop=True)
步骤2:标记州行并关联城市
利用州名全大写的特征标记州行,再用前向填充(ffill)把州名传递给后续的城市行,最后过滤掉州行即可:
# 标记哪些行是州(全大写的字符串) df_clean['is_state'] = df_clean['citystate'].str.isupper() # 用前向填充,让每个城市都关联到最近的州 df_clean['state'] = df_clean.loc[df_clean['is_state'], 'citystate'].ffill() # 过滤掉州行,只保留城市行,并重命名列 result = df_clean[~df_clean['is_state']].rename(columns={'citystate': 'city'})[['state', 'city']] # 输出结果 print(result)
输出结果
运行后你会得到想要的两列结构:
state city 1 ALABAMA Birmingham 2 ALABAMA Montgomery 3 ALABAMA Huntsville 4 CALIFORNIA Los Angeles 5 CALIFORNIA San Diego 6 CALIFORNIA Fresno
适配非全大写州名的情况
如果你的州名不是全大写,可以根据原数据“州的下一行是NaN”的规律来标记州行:
# 标记州行:当前行非空,且下一行是空值(NaN) df['is_state'] = df['citystate'].notna() & df['citystate'].shift(-1).isna() # 后续步骤和上面一致:删除NaN行、前向填充、过滤州行 df_clean = df.dropna().reset_index(drop=True) df_clean['state'] = df_clean.loc[df_clean['is_state'], 'citystate'].ffill() result = df_clean[~df_clean['is_state']].rename(columns={'citystate': 'city'})[['state', 'city']]
内容的提问来源于stack exchange,提问作者Pi-thon
相关产品推荐
相关产品推荐

