我可以通过编写一个 for 循环来解决我的任务,但我想知道如何以更受欢迎的方式来完成此任务。
所以我有这个数据框存储一些列表,并希望找到这些列表中具有公共(public)值的所有行,
(此代码只是为了获取带有列表的 df:
>>> df = pd.DataFrame( {'a':['A','A','B','B','B','C'], 'b':[1,2,5,1,4,6]})
>>> df
a b
0 A 1
1 A 2
2 B 5
3 B 1
4 B 4
5 C 6
>>> d = df.groupby('a')['b'].apply(list)
)
我们从这里开始:
>>> d
A [1, 2]
B [5, 1, 4]
C [6]
Name: b, dtype: object
我想选择索引为“A”和“B”的行,因为它们的列表重叠值 1。
我现在可以编写一个 for 循环或在这些列表中扩展数据帧(与上面的方式相反),并有多行复制其他值。 你会在这里做什么?或者有什么方法可以使用 df.groupby(by=lambda x, y : return not set(x).isdisjoint(y)) 来比较两行? 但是 groupby 和 bool 掩码只是一次查看一个元素......
<小时/>我现在尝试重载列表的相等运算符,并且因为列表不可散列,所以重载元组和集合的相等运算符(我将散列设置为 1 以避免身份比较)。然后我使用 groupby 并在框架上与自身合并,但看起来,它检查了索引,它已经匹配了。
import pandas as pd
import numpy as np
from operator import itemgetter
class IndexTuple(set):
def __hash__(self):
#print(hash(str(self)))
return hash(1)
def __eq__(self, other):
#print("eq ")
is_equal = not set(self).isdisjoint(other)
return is_equal
l = IndexTuple((1,7))
l1 = IndexTuple((4, 7))
print (l == l1)
df = pd.DataFrame(np.random.randint(low=0, high=4, size=(10, 2)), columns=['a','b']).reset_index()
d = df.groupby('a')['b'].apply(IndexTuple).to_frame().reset_index()
print (d)
print (d.groupby('b').b.apply(list))
print (d.merge (d, on = 'b', how = 'outer'))
输出(它对于第一个元素工作正常,但在 [{3}]
处应该是 [{3},{0,3}]
:
True
a b
0 0 {1}
1 1 {0, 2}
2 2 {3}
3 3 {0, 3}
b
{1} [{1}]
{0, 2} [{0, 2}, {0, 3}]
{3} [{3}]
Name: b, dtype: object
a_x b a_y
0 0 {1} 0
1 1 {0, 2} 1
2 1 {0, 2} 3
3 3 {0, 3} 1
4 3 {0, 3} 3
5 2 {3} 2
最佳答案
在df
上使用合并
:
v = df.merge(df, on='b')
common_cols = set(
np.sort(v.iloc[:, [0, -1]].query('a_x != a_y'), axis=1).ravel()
)
common_cols
{'A', 'B'}
现在,预过滤并调用groupby
:
df[df.a.isin(common_cols)].groupby('a').b.apply(list)
a
A [1, 2]
B [5, 1, 4]
Name: b, dtype: object
关于python - 在 pandas 数据框中查找行,其中不同的行在存储列表的列的列表中具有公共(public)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49455620/