【问题标题】:Avoid nested loops when iterating over Pandas DataFrame with condition over items使用条件对项进行迭代 Pandas DataFrame 时避免嵌套循环
【发布时间】:2019-07-31 23:34:40
【问题描述】:

以下代码遍历 Pandas DataFrame 的每个成员,询问项目的绝对值是否 >= 0.5,如果是,则将其值与相应的列和行名称一起附加到列表中:

record = []
for i in range(df.shape[0]):
    for j in range(df.shape[1]):
        if abs(df.iloc[i, j]) >= 0.5:
            record.append([df.columns[j], df.index[i], df.iloc[i, j]])

当然,这可能需要一些时间,具体取决于数据帧的大小,因为执行这些嵌套循环的效率非常低...

有没有更好、更快、更 Pythonic 的方式来做到这一点?

示例输入:

      colA  colB  colC  colD
row1  -0.7   0.3   0.6  -0.2
row2   0.4  -0.3   0.8  -0.9

样本输出:

[['colA', 'row1', -0.7],
 ['colC', 'row1', 0.6],
 ['colC', 'row2', 0.8],
 ['colD', 'row2', -0.9]]

【问题讨论】:

  • 您应该添加一个可以由我们复制的小示例数据集。根据该示例,您的预期输出是什么。
  • @Erfan,感谢您的提醒。就这么做了。

标签: python pandas loops dataframe nested


【解决方案1】:

这是mask整个df的值然后stack的一种方式

df.where(df.abs()>0.5).stack().reset_index().values.tolist()

【讨论】:

    【解决方案2】:

    使用 numpy.将 pandas 数据框的值转换为 numpy:

    import numpy as np
    
    A = df.to_numpy()  
    

    为了获得数据,我先随机生成它们,然后挑选出大于 0.5 的数据:

    A = np.random.randn(3, 6)
    B = A[A>=0.5]
    B
    
    array([0.87244799, 1.35438111, 1.18743473, 0.65015131, 0.71182848,
           0.85945553, 2.02416415, 0.53008776])
    

    【讨论】:

    • 问题是:(1) 只获取 >= 0.5 的项目(而不是绝对值 >= 0.5 的项目),但我相信可以通过将“A >= 0.5”更改为“np.abs(A) >= 0.5”; (2) 它没有得到列名和行名。
    • 第 (2) 点很简单:当我们在 numpy 中获得正确的输出时,我们可以将其再次转换回 pandas 数据帧。
    • 与此同时,您显然已经在问题中添加了首选输出,这很好,然后它与我从没有它的问题中得到的结果非常不同。 (我不知道,否决票来自哪里。但至少我们尝试与您合作并为您服务)
    猜你喜欢
    • 2019-11-30
    • 2021-12-28
    • 2018-11-09
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多