我正在尝试查找一个DataFrame(df_other
(中与另一个DataFrame(df
(中的列匹配的元素。换句话说,对于df['a']
中的每一行,我想知道df['a']
中的值与df_other['a']
中的值在哪里匹配。
一个例子可能更容易解释预期结果:
>>> import pandas as pd
>>> import numpy as np
>>>
>>>
>>> df = pd.DataFrame({'a': ['x', 'y', 'z']})
>>> df
a
0 x
1 y
2 z
>>> df_other = pd.DataFrame({'a': ['x', 'x', 'y', 'z', 'z2'], 'c': [1, 2, 3, 4, 5]})
>>> df_other
a c
0 x 1
1 x 2
2 y 3
3 z 4
4 z2 5
>>>
>>>
>>> u = df_other['c'].unique()
>>> u
array([1, 2, 3, 4, 5])
>>> bm = np.ones((len(df), len(u)), dtype=bool)
>>> bm
array([[ True, True, True, True, True],
[ True, True, True, True, True],
[ True, True, True, True, True]])
应该产生的位图
[
[1, 1, 0, 0, 0], # [1, 2] are df_other['c'] where df_other['a'] == df['a']
[0, 0, 1, 0, 0], # [3] matches
[0, 0, 0, 1, 0], # [4] matches
]
我正在寻找一个不遍历所有行的快速numpy实现(这是我目前的解决方案(:
>>> df_other['a'] == df.loc[0, 'a']
0 True
1 True
2 False
3 False
4 False
Name: a, dtype: bool
>>>
>>>
>>> df_other['a'] == df.loc[1, 'a']
0 False
1 False
2 True
3 False
4 False
Name: a, dtype: bool
>>> df_other['a'] == df.loc[2, 'a']
0 False
1 False
2 False
3 True
4 False
Name: a, dtype: bool
注意:在实际的生产代码中,有更多的列条件((df['a'] == df_other['a']) & (df['b'] == df_other['b'] & ...
(,但它们通常小于df
中的行数,所以我不介意在这些条件上循环(然后将bm
中的值设置为false(的解决方案。
此外,位图的形状应为(len(df), len(df_other['c'].unique))
。
numpy广播在这里非常有用:
bm = df_other.values[:, 0] == df.values
输出:
>>> bm
array([[ True, True, False, False, False],
[False, False, True, False, False],
[False, False, False, True, False]])
如果你需要它作为int:
>>> bm.astype(int)
array([[1, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0]])
使用panda方法的另一种方法如下:
pd.crosstab(df_other['a'], df_other['c']).reindex(df['a']).to_numpy(dtype=int)
输出:
array([[1, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0]])