有效选择numpy中的值



我正在尝试查找一个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]])

最新更新