【问题标题】:Using A For Loop to Return Unique Values in a Pandas Dataframe使用 For 循环返回 Pandas 数据框中的唯一值
【发布时间】:2016-08-21 15:25:18
【问题描述】:

我知道 Pandas 并不是真正为与 for 循环一起使用而构建的,但我有一个特定的任务我必须做很多次,如果我可以将其中的一些抽象出来,真的会节省很多时间有一个我可以调用的函数。

我的数据框的通用版本如下所示:

df = pd.DataFrame({'Name': pd.Categorical(['John Doe', 'Jane Doe', 'Bob Smith']), 'Score1': np.arange(3), 'Score2': np.arange(3, 6, 1)})

        Name  Score1  Score2
0   John Doe       0       3
1   Jane Doe       1       4
2  Bob Smith       2       5

我要做的是采取方法:

df.loc[df.Name == 'Jane Doe', 'Score2']

应该返回 4,但使用这样的 for 循环遍历它:

def pull_score(people, score):    
    for i in people:
        print df.loc[df.Name == people[i], score]

所以如果我愿意,我可以打电话:

the_names = ['John Doe', 'Jane Doe', 'Bob Smith']
pull_score(the_names, 'Score2')

得到:

3
4
5

我目前得到的错误信息是:

TypeError: list indices must be integers, not str

我查看了与此错误消息和 Pandas 相关的其他一些答案,例如这个:Python and JSON - TypeError list indices must be integers not str 和这个:How to solve TypeError: list indices must be integers, not list?

但没有看到我正在尝试做的事情的答案,我不相信iterrows()itertuple() 会适用,因为我需要 Pandas 先找到值。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以将名称设置为索引,然后使用loc按索引搜索:

    the_names = ['John Doe', 'Jane Doe', 'Bob Smith']
    df.set_index('Name').loc[the_names, 'Score2']
    
    # Name
    # John Doe     3
    # Jane Doe     4
    # Bob Smith    5
    # Name: Score2, dtype: int32
    

    【讨论】:

      【解决方案2】:

      首先要做的事情。你的逻辑有一个错误,当你建立你的for循环时,你使用people中的东西就好像它们是people列表的索引,而它们是people中的东西。所以相反,做

      def pull_score(df, people, score):
          for i in people:
              print df.loc[df.Name == i, score]
      
      the_names = ['John Doe', 'Jane Doe', 'Bob Smith']
      pull_score(df, the_names, 'Score2')
      
      0    3
      Name: Score2, dtype: int64
      1    4
      Name: Score2, dtype: int64
      2    5
      Name: Score2, dtype: int64
      

      既然已经说过了,我将跳上其他回答者的同一个潮流,说明使用内置的 pandas 功能有更好的方法来做到这一点。以下是我尝试在以提供解决方案的用户命名的函数中捕获每个解决方案尝试执行的操作。我建议 pir 是最有效的,因为它使用的功能旨在完成这项任务。

      def john(df, people, score):
          s = pd.Series([])
          for i in people:
              s = s.append(df.loc[df['Name'] == i, score])
          return s
      
      def psidom(df, people, score):
          return df.set_index('Name').loc[people, score]
      
      def pir(df, people, score):
          return df.loc[df['Name'].isin(people), score]
      

      时间

      【讨论】:

        【解决方案3】:

        你实际上不需要循环,你可以这样做:

        print(df.loc[df.Name == the_names, 'Score2'])
        0    3
        1    4
        2    5
        Name: Score2, dtype: int32
        

        【讨论】:

        • 这是不准确的。它只是巧合地适用于所述的测试用例。尝试df.loc[df.Name == the_names[:2], 'Score2'] 失败!
        猜你喜欢
        • 2018-10-15
        • 2021-09-23
        • 2020-08-06
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 2020-06-14
        • 2020-03-01
        • 1970-01-01
        相关资源
        最近更新 更多