【问题标题】:Pandas: Alternative to iterrow loopsPandas:迭代循环的替代方案
【发布时间】:2018-06-06 09:52:53
【问题描述】:

我在 pandas 中运行了一个小函数,当我运行 if x in y 语句时会引发 ValueError。我看到推荐布尔索引、.isin()where() 的类似问题,但我无法根据我的情况调整任何示例。任何建议将不胜感激。

附加说明:groups 是包含数据框之外的字符串的列表列表。我使用该函数的目标是查看数据框中的项目在哪个列表中,然后返回该列表的索引。我在下面的笔记本链接中的第一个版本使用iterrows 循环遍历数据帧,但我知道在大多数情况下这是次优的。

带有一些虚假数据的 Jupyter 笔记本:https://github.com/amoebahlan61/sturdy-chainsaw/blob/master/Grouping%20Test_1.1.ipynb

谢谢!

代码:

def groupFinder(item):
    for group in groups:
        if item in group:
            return groups.index(group)

df['groupID2'] = groupFinder(df['item'])


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-16-808ac3e51e1f> in <module>()
      4             return groups.index(group)
      5 
----> 6 df['groupID2'] = groupFinder(df['item'])

<ipython-input-16-808ac3e51e1f> in groupFinder(item)
      1 def groupFinder(item):
      2     for group in groups:
----> 3         if item in group:
      4             return groups.index(group)
      5 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
    953         raise ValueError("The truth value of a {0} is ambiguous. "
    954                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
--> 955                          .format(self.__class__.__name__))
    956 
    957     __bool__ = __nonzero__

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

解决方案 我遇到了一些 pandas 的博客文章,还从 reddit 用户那里得到了一些反馈,这给了我一个解决方案,通过使用 pandas 的 apply 函数跳过使用 iterrows

df['groupID2'] = df.item.apply(groupFinder)

感谢大家的帮助和回复。

【问题讨论】:

  • 一般来说,在问题中包含指向数据的链接并不是一个好主意 - 链接可能会失效,一方面,另一方面,它更难帮助您。在这种情况下,单击您的链接 also 不会转到您的笔记本(尽管将 URL 字符串复制到浏览器中有效)。为了其他可能使用您的问题作为参考的人的利益,请考虑将您的示例数据和设置移动到您的帖子文本中,作为Minimal, Complete, and Verifiable Example
  • @andrew_reece 感谢您提出问题和代码礼仪。我一定会继续使用它。

标签: python pandas numpy dataframe


【解决方案1】:

使用isin的方法是先调用Series.isin(...)产生一个布尔掩码,然后使用这个掩码进行索引。或者,要在列表而不是系列上使用您的函数,您可以调用 groupFinder(df['item'].values)

【讨论】:

    【解决方案2】:

    IIUC,您可以使用 Pandas 只需几行代码即可完成您想要的操作:

    import pandas as pd
    
    # create master list of items
    master = pd.Series(legumesGroup + herbGroup + radishGroup)
    
    # assign group id as index
    master.index = [0]*len(legumesGroup) + [1]*len(herbGroup) + [2]*len(radishGroup)
    
    # sample from master with replacement to get itemList
    itemList = master.sample(n=1000, replace=True)
    

    现在要获取 itemList 中的每个项目所在的组,请调用 itemList 以查看组 ID 和项目,或者直接调用 itemList.index

    itemList.head()
    

    输出:

    2        Horseradish
    2           Rutabaga
    2             Turnip
    0          Chickpeas
    0        Pinto beans
    

    【讨论】:

    • 这是一个非常有趣的解决方案。我不会考虑为组项添加索引值。谢谢!
    【解决方案3】:

    解决方案

    我看到了一些 pandas 的博客文章,并且还从一个 reddit 用户那里得到了一些反馈,这给了我一个解决方案,通过使用 pandas 的 apply 函数来跳过使用 iterrows。

    df['groupID2'] = df.item.apply(groupFinder)
    

    感谢大家的帮助和回复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-06
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 2020-03-21
      • 1970-01-01
      • 2021-12-28
      相关资源
      最近更新 更多