我正在使用itertuples()迭代器函数迭代pandas表。当条件为True时,我想在另一列中设置一个值。这很简单。但是我想再次根据先前设置的值将另一个值设置为另一列,这样就不起作用了。我必须第二次做到这一点,但这是低效的。 如何在一个迭代过程中在不同的列中设置多个值。
以下是一些示例代码:
data = {
'Animal': ['cat', 'dog', 'dog', 'cat', 'bird', 'dog', 'cow'],
'Noise': ['muh', 'miau', 'wuff', 'piep', 'piep', 'miau', 'muh']
}
df = pd.DataFrame(data)
df.insert(loc=2, column='Match', value='')
df.insert(loc=3, column='Comment', value='')
for row in df.itertuples():
if row.Animal == 'cat' and row.Noise == 'miau':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'dog' and row.Noise == 'wuff':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'bird' and row.Noise == 'piep':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'cow' and row.Noise == 'muh':
df.set_value(index=row.Index, col='Match', value=True)
# Why is this not getting applied to the 'Comment' column?
if row.Match is True:
df.set_value(index=row.Index, col='Comment', value='yeah')
我必须做另一次迭代而不是填充Comment-column:
for row in df.itertuples():
if row.Match is True:
df.set_value(index=row.Index, col='Comment', value='yeah')
但是,即使用500000+值,这也非常低效且耗时。 那么做什么更好的方法呢?
答案 0 :(得分:1)
考虑您的df
data = {
'Animal': ['cat', 'dog', 'dog', 'cat', 'bird', 'dog', 'cow'],
'Noise': ['muh', 'miau', 'wuff', 'piep', 'piep', 'miau', 'muh']
}
df = pd.DataFrame(data)
我使用最初计算的字典来定义匹配的内容。然后,使用map
转换并测试相等性。之后,我会使用assign
生成所需的列。
matches = dict(cat='miau', dog='wuff', bird='piep', cow='muh')
match = df.Animal.map(matches) == df.Noise
df.assign(Match=match, Comment=np.where(match, 'yeah', ''))
Animal Noise Match Comment
0 cat muh False
1 dog miau False
2 dog wuff True yeah
3 cat piep False
4 bird piep True yeah
5 dog miau False
6 cow muh True yeah
回答您的具体问题:
循环中的row
不再附加到数据框。因此,当您使用True
将False
或set_value
分配给数据框时,您将无法访问刚刚从row
设置的值。相反,请使用df.get_value
for row in df.itertuples():
if row.Animal == 'cat' and row.Noise == 'miau':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'dog' and row.Noise == 'wuff':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'bird' and row.Noise == 'piep':
df.set_value(index=row.Index, col='Match', value=True)
elif row.Animal == 'cow' and row.Noise == 'muh':
df.set_value(index=row.Index, col='Match', value=True)
# This should work
if df.get_value(index=row.Index, col='Match') is True:
df.set_value(index=row.Index, col='Comment', value='yeah')
答案 1 :(得分:0)
而不是
# Why is this not getting applied to the 'Comment' column?
if row.Match is True:
df.set_value(index=row.Index, col='Comment', value='yeah')
你可以在for循环之后使用它。
df['Comment'] = df['Match'].apply(lambda x: 'yeah' if x == True else '')