遍历 Pandas DataFrame 中的行,转换为字典形式。

32

我需要迭代pandas数据框以便将每一行作为函数(实际上是类构造函数)的参数传递,使用**kwargs。这意味着每一行应该像字典一样运作,其中键是列名,值是每一行对应的值。

这是可行的,但效率非常低:

import pandas as pd


def myfunc(**kwargs):
    try:
        area = kwargs.get('length', 0)* kwargs.get('width', 0)
        return area
    except TypeError:
        return 'Error : length and width should be int or float'


df = pd.DataFrame({'length':[1,2,3], 'width':[10, 20, 30]})

for i in range(len(df)):
    print myfunc(**df.iloc[i])

有没有建议如何使其更高效?我尝试使用 df.iterrows() 遍历,但是出现以下错误:

TypeError: myfunc() argument after ** must be a mapping, not tuple

我也尝试过使用 df.itertuples()df.values,但是要么我漏掉了什么,要么这意味着我必须将每个元组/np.array转换为 pd.Series 或 dict,这也会很慢。 我的限制是脚本必须在 Python 2.7 和 Pandas 0.14.1 中运行。


请尝试使用DataFrame.iterrows - Itay
你的代码中最慢的部分是打印面积。如果我在Python 3中尝试使用10,000行,使用你的变量(不打印)需要1.5秒,使用itterrows()需要0.9秒,而如果我打印面积,则需要超过3秒。 - Florian H
谢谢您的建议。我已经尝试过了,但是似乎不知道如何访问每行元素的列名。至于打印输出,我只是为了代码的可执行性而写的,迭代性能才是最重要的。 - Matina G
3个回答

67

一个干净的选项是这个:

for row_dict in df.to_dict(orient="records"):
    print(row_dict['column_name'])

2
这是最好的答案。 - Iván
2
根据最新文档,现在应该使用 orient='records':https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_dict.html - Roy Shilkrot
1
如果您想要键和值,请使用“index”而不是“records”。然后还必须使用items()来迭代键/值。 - David Waterworth
3
这也是在迭代行时避免像 .iterrows() 那样强制转换数据类型或者像 itertuples() 那样重命名具有无效 Python 标识符的列的最佳方法。 - jfaccioni

24
您可以尝试:

您可以尝试:

for k, row in df.iterrows():
    myfunc(**row)

这里k是数据帧的索引,row是一个字典,因此您可以使用以下方式访问任何列:row["my_column_name"]


1
这是一个不错的解决方案,但要注意在大型数据集中使用iterrows会影响性能请参见此处 - Karn Kumar
1
没错,我只是为了让iterrows起作用而回答的,但@jpp的解决方案在性能方面可能更好。 - stellasia
实际上它是一个 pd.Series 而不是一个 __dict__。但它当然可以工作。 - Diogo Santiago

1
为此定义一个单独的函数将是低效的,因为您正在应用逐行计算。更有效的方法是计算新系列,然后迭代该系列:
df = pd.DataFrame({'length':[1,2,3,'test'], 'width':[10, 20, 30,'hello']})

df2 = df.iloc[:].apply(pd.to_numeric, errors='coerce')

error_str = 'Error : length and width should be int or float'
print(*(df2['length'] * df2['width']).fillna(error_str), sep='\n')

10.0
40.0
90.0
Error : length and width should be int or float

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接