使用For循环返回Pandas Dataframe中的唯一值

时间:2016-08-20 23:39:35

标签: python pandas

我知道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首先找到值

3 个答案:

答案 0 :(得分:3)

您可以将名称设置为索引,然后使用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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

首先要做的事情。您的逻辑中存在错误,因为当您建立for循环时,您使用people中的内容,就好像它们是列表people的索引一样people {1}}。所以相反,做

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]

时序

enter image description here