网友问题:
我有一个熊猫数据帧,:df
c1 c2
0 10 100
1 11 110
2 12 120
如何循环访问此数据帧的行?对于每一行,我希望能够通过列的名称访问其元素(单元格中的值)。例如:
for row in df.rows:
print(row['c1'], row['c2'])
我发现了一个类似的问题,建议使用以下任一问题:
for date, row in df.T.iteritems():
for row in df.iterrows():
但我不明白对象是什么以及如何使用它。row
网友回答:
1、
DataFrame.iterrows
是一个生成索引和行的生成器(作为一个系列):
import pandas as pd
df = pd.DataFrame({'c1': [10, 11, 12], 'c2': [100, 110, 120]})
df = df.reset_index() # make sure indexes pair with number of rows
for index, row in df.iterrows():
print(row['c1'], row['c2'])
10 100
11 110
12 120
2、
如何在 Pandas 中循环访问数据帧中的行
答:不要*!
Pandas 中的迭代是一种反模式,只有在用尽所有其他选项后才应该这样做。您不应该使用名称中带有“”的任何函数超过几千行,否则您将不得不习惯于大量的等待。iter
是否要打印数据帧?使用 DataFrame.to_string()。
你想计算什么吗?在这种情况下,请按以下顺序搜索方法(从此处修改的列表):
for
DataFrame.apply(
): i) 可以在 Cython 中执行的归约,ii) Python 空间中的迭代DataFrame.itertuples
() 和 iteritems()
DataFrame.iterrows()
iterrows
并且(两者都在回答这个问题时获得许多投票)应该在非常罕见的情况下使用,例如生成行对象/名称元组以进行顺序处理,这实际上是这些函数唯一有用的东西。itertuples
向当局上诉
关于迭代的文档页面有一个巨大的红色警告框,上面写着:
遍历 pandas 对象通常很慢。在许多情况下,不需要手动迭代行 […]。
*它实际上比“不要”要复杂一些。df.iterrows()
是这个问题的正确答案,但“矢量化你的操作”是更好的答案。我承认在某些情况下无法避免迭代(例如,某些操作的结果取决于为前一行计算的值)。但是,需要熟悉库才能知道何时。如果您不确定是否需要迭代解决方案,则可能不需要。PS:要了解更多关于我写这个答案的理由,请跳到最底部。
大量的基本操作和计算被熊猫“矢量化”(通过NumPy,或通过Cythonized函数)。这包括算术、比较、(大多数)约简、重塑(如透视)、联接和分组依据运算。浏览有关基本基本功能的文档,找到适合您问题的矢量化方法。
如果不存在,请随意使用自定义 Cython 扩展编写自己的扩展。
如果 1) 没有可用的矢量化解决方案,2) 性能很重要,但还不够重要,无法经历代码的麻烦,以及 3) 您正在尝试对代码执行元素转换,则列表推导应该是您的下一个停靠港。有大量证据表明,对于许多常见的Pandas任务,列表理解足够快(有时甚至更快)。
公式很简单,
# Iterating over one column - `f` is some function that processes your data
result = [f(x) for x in df['col']]
# Iterating over two columns, use `zip`
result = [f(x, y) for x, y in zip(df['col1'], df['col2'])]
# Iterating over multiple columns - same data type
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].to_numpy()]
# Iterating over multiple columns - differing data type
result = [f(row[0], ..., row[n]) for row in zip(df['col1'], ..., df['coln'])]
如果可以将业务逻辑封装到函数中,则可以使用调用它的列表推导。您可以通过原始 Python 代码的简单性和速度使任意复杂的事情工作。
警告
列表推导假设您的数据易于使用 – 这意味着您的数据类型是一致的并且您没有NaN,但这并不总是可以保证的。
zip(df['A'], df['B'], ...)
df[['A', 'B']].to_numpy()
to_numpy()
zip
*您的里程可能会因上述注意事项部分所述原因而有所不同。
对iter家族的各种替代品进行的大多数分析都是通过性能的视角进行的。但是,在大多数情况下,您通常会处理大小合理的数据集(不超过几千或 100K 行),性能将次于解决方案的简单性/可读性。
这是我在选择用于解决问题的方法时的个人偏好。
对于新手:
矢量化(如果可能);
应用()
;列出理解;itertuples
()/iteritems()
;迭代()
;赛通
对于更有经验的人:
矢量化(如果可能);
应用()
;列出理解;赛通;itertuples
()/iteritems()
;迭代行()
矢量化是任何可以矢量化问题的最惯用方法。始终寻求矢量化!如有疑问,请查阅文档,或在 堆栈溢出 查找有关您的特定任务的现有问题。
我确实倾向于在我的很多帖子中继续谈论有多糟糕,但我确实承认初学者更容易理解它在做什么。此外,在我的这篇文章中已经解释了相当多的用例。apply
apply
Cython在列表中排名较低,因为它需要更多的时间和精力才能正确完成。你通常永远不需要用 pandas 编写代码,这需要这种性能水平,即使是列表理解也无法满足。
* 与任何个人意见一样,请带上盐堆!
apply
iter*
apply
GroupBy
* Pandas 字符串方法是“矢量化”的,因为它们在序列上指定,但对每个元素进行操作。底层机制仍然是迭代的,因为字符串操作本质上很难矢量化。
我从新用户那里注意到的一个常见趋势是提出“我如何迭代我的 df 来做 X?”形式的问题。显示在循环内执行某些操作时调用的代码。原因如下。尚未了解矢量化概念的库新用户可能会将解决问题的代码设想为迭代其数据以执行某些操作。不知道如何迭代数据帧,他们做的第一件事就是谷歌它并结束在这里,在这个问题上。然后,他们看到接受的答案告诉他们如何操作,然后他们闭上眼睛运行此代码,而无需首先质疑迭代是否正确。iterrows()
for
这个答案的目的是帮助新用户理解迭代不一定是每个问题的解决方案,并且可能存在更好,更快和更惯用的解决方案,并且值得花时间探索它们。我并不是要发起一场迭代与矢量化的战争,但我希望新用户在开发有关此库问题的解决方案时了解情况。
3、
首先考虑是否确实需要循环访问数据帧中的行。有关替代方案,请参阅此答案。
如果仍需要迭代行,可以使用以下方法。请注意一些重要的警告,这些警告在任何其他答案中都没有提到。
for index, row in df.iterrows():
print(row["c1"], row["c2"])
for row in df.itertuples(index=True, name='Pandas'):
print(row.c1, row.c2)
itertuples()
应该比iterrows()
但请注意,根据文档(目前 pandas 0.24.2):
dtype
由于迭代行为每一行返回一个序列,因此它不会跨行保留 dtype(dtype 在数据帧的列中保留)。为了在迭代行时保留 dtype,最好使用 itertuples(),它返回值的命名元组,并且通常比 iterrows() 快得多。
你永远不应该修改你正在迭代的东西。这并不能保证在所有情况下都有效。根据数据类型,迭代器返回副本而不是视图,写入该副本将不起作用。
请改用 DataFrame.apply():
new_df = df.apply(lambda x: x * 2, axis = 1)
如果列名称是无效的 Python 标识符、重复或以下划线开头,则列名称将重命名为位置名称。对于大量列 (>255),将返回常规元组。
有关更多详细信息,请参阅有关迭代的熊猫文档。
模板简介:该模板名称为【如何在 Pandas 中循环访问数据帧中的行】,大小是暂无信息,文档格式为.html,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Python】栏目查找您需要的精美模板。