Pandas中按条件复制DataFrame行时列转行问题的解决方法
解决Pandas筛选后DataFrame形状不一致的问题
嘿,作为Pandas新手碰到这种结构变形的问题太正常啦,我来帮你捋清楚问题出在哪,以及怎么快速解决~
问题根源
你原来的代码用iterrows()循环赋值时,每次的row其实是一个Series(一维数据结构),每次赋值都会把之前的dr1/dr2覆盖掉,最后只剩循环的最后一行数据,而且是一维的Series,看起来就像是把原DataFrame的行转成了列,自然和原结构不一致。另外,iterrows()本身效率极低,Pandas官方也不推荐用它来做这种批量筛选操作。
最优解决方案:用矢量化布尔索引(强烈推荐)
Pandas最擅长的就是矢量化操作,直接用条件筛选整行数据,一步到位得到和原DataFrame结构完全一致的结果:
import pandas as pd # 假设today和tomo是你已经定义好的datetime对象 # 先构建筛选条件:Level :列的日期天是今天或明天 condition = dr['Level :'].dt.day.isin([today.day, tomo.day]) # 用布尔索引拆分DataFrame,copy()避免后续修改原数据的视图问题 dr1 = dr[condition].copy() dr2 = dr[~condition].copy() # ~符号表示取反,筛选不满足条件的行
这样得到的dr1和dr2都是和原dr结构、列名完全一致的DataFrame,绝对不会出现行转列的问题,而且运行速度比循环快N倍!
如果一定要用循环(仅作理解用,不推荐)
要是你想搞清楚循环该怎么写才能得到正确结构,可以先初始化空的DataFrame,然后每次把循环的row转成DataFrame再追加进去:
# 初始化和原dr结构一致的空DataFrame dr1 = pd.DataFrame(columns=dr.columns) dr2 = pd.DataFrame(columns=dr.columns) for index, row in dr.iterrows(): # 注意这里直接用row['Level :'],不用dr['Level :'][index],更高效 if row['Level :'].day == today.day or row['Level :'].day == tomo.day: # 把row转成单行DataFrame,再追加到dr1里 dr1 = pd.concat([dr1, row.to_frame().T], ignore_index=True) else: dr2 = pd.concat([dr2, row.to_frame().T], ignore_index=True)
不过还是要提醒下,这种方法在数据量大的时候会非常慢,所以尽量用第一种矢量化的方法哦~
内容的提问来源于stack exchange,提问作者Bhargav
相关产品推荐
相关产品推荐

