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