如何解决迭代Pandas DataFrame行生成新DataFrame时的行列颠倒问题
嘿,这个问题我之前踩过坑!你遇到的行列颠倒问题,核心原因是直接append一个Series时,pandas默认会把它当作一列来处理,自然就搞反了行列。另外还有个容易忽略的点:append方法不会修改原DataFrame,它会返回一个新的对象,所以你得把结果重新赋值回去才行。
下面给你几种解决方案,从修复现有代码到更高效的pandas原生操作都有:
1. 修复你的循环代码
把每个Series转成单行的DataFrame再追加,同时记得赋值:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randint(low=0, high=10, size=(5, 5)), columns=['a', 'b', 'c', 'd', 'e']) df1 = pd.DataFrame() df2 = pd.DataFrame() for index, row in df.iterrows(): # 替换成你的实际判断条件 if row['a'] > 5: # 将Series转置为单行DataFrame,ignore_index避免索引混乱 df1 = df1.append(row.to_frame().T, ignore_index=True) else: df2 = df2.append(row.to_frame().T, ignore_index=True)
这里row.to_frame()会把Series变成单列的DataFrame,.T转置成单行,ignore_index=True确保新DataFrame的索引是连续的。
2. 推荐:用布尔索引直接筛选(效率最高)
pandas的核心优势就是向量式操作,循环iterrows其实是效率很低的做法,尤其是数据量大的时候。直接用布尔索引拆分DataFrame才是最优解:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randint(low=0, high=10, size=(5, 5)), columns=['a', 'b', 'c', 'd', 'e']) # 定义你的筛选条件,比如a列的值大于5 condition = df['a'] > 5 # 直接按条件拆分,copy避免后续修改影响原DataFrame df1 = df[condition].copy() df2 = df[~condition].copy()
这种写法不仅简洁,速度比循环快几个量级,完全符合pandas的设计思路。
3. 折中方案:收集Series到列表再统一转换
如果因为某些原因必须用循环,那尽量不要在循环里反复append(每次append都会创建新对象,非常耗资源),而是先把符合条件的Series收集到列表,最后一次性转成DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randint(low=0, high=10, size=(5, 5)), columns=['a', 'b', 'c', 'd', 'e']) list_df1 = [] list_df2 = [] for index, row in df.iterrows(): if row['a'] > 5: list_df1.append(row) else: list_df2.append(row) # 把列表里的Series直接转成DataFrame,重置索引 df1 = pd.DataFrame(list_df1).reset_index(drop=True) df2 = pd.DataFrame(list_df2).reset_index(drop=True)
这种方法比循环append高效很多,而且代码也更清晰。
内容的提问来源于stack exchange,提问作者Yogi
相关产品推荐
相关产品推荐

