我有以下数据框:
>>> df = pd.DataFrame({'col1': [1, 2, 1], 'col2': [6, 3, 6]})
>>> df
col1 col2
0 1 6
1 2 3
2 1 6
和以下词典:
>>> di = {'col1': 1, 'col2': 6}
>>> di
{'col2': 6, 'col1': 1}
我正在寻找能够遍历 di 的解决方案,并在 df 中找到匹配的行。我不想写一行专门使用列名和值的行。我在论坛上看到了这些解决方案,这不是我想在这里做的。 (可怕的非)解决方案是:
is_not_first = True
tf_series = None
for key, val in di.iteritems():
if is_not_first:
tf_series = (tf_series & (df[key] == val))
else:
tf_series = (df[key] == val)
is_not_first = False
我打算稍后使用 tf_series 在 df 中设置另一列:
df.loc[tf_series, 'col3'] = True
从我见过的许多优秀的熊猫帖子来看,我确信有更简洁的东西,更不用说,实际上有用的东西。谢谢!
答案 0 :(得分:3)
您可以将所有逻辑合并为一行,而不是构建冗余系列,您可以构建另一个与 df 具有相同索引/列的DataFrame并分配给{{1}直接,这是实现这一目标的一种方法:
df['col3']
使用地图:
的快速和缺省版本In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'col1': [1, 2, 1], 'col2': [6, 3, 6]})
In [3]: di = {'col1': 1, 'col2': 6}
In [4]: df['col3'] = pd.DataFrame([df[k]==v for k,v in di.iteritems()]).all()
In [5]: df
Out[5]:
col1 col2 col3
0 1 6 True
1 2 3 False
2 1 6 True
如果您查看列表,当您重复字典 di 时,它会为您提供键/值对,这实际上是是原始 df 的列/值。
因此,In [6]: df['col3'] = pd.DataFrame(map(lambda k: df[k]==di[k], di)).all()
会为您提供价值,并将其与字典' v 进行比较,产生真/假。
df[column]
然后根据该结果构建一个阴影DataFrame,将为您提供:
In [8]: [df[k]==v for k,v in di.iteritems()]
Out[8]:
[0 True
1 False
2 True
Name: col2, dtype: bool, 0 True
1 False
2 True
Name: col1, dtype: bool]
正如@ant指出的那样,我错误地使用了 any(),而 all()则应该满足所有pd.DataFrame([df[k]==v for k,v in di.iteritems()])
Out[9]:
0 1 2
col2 True False True
col1 True False True
值:< / p>
最后,所有()返回索引/结果,其上方的列符合所有 True 条件:
True
您只需将此结果列指定给In [10]: pd.DataFrame([df[k]==v for k,v in di.iteritems()]).all()
Out[10]:
0 True
1 False
2 True
dtype: bool
,即可完成。
要避免df['col3']
警告,您只需要将一个班轮分成2:
SettingWithCopy