熊猫字符串列的交集/子集

时间:2019-06-10 20:10:57

标签: python pandas networkx graph-theory intersection

我有一个带有以下结构的pandas数据框:

>> print(df)

id      time      amount      seller     buyer
-------------------------------------------------
1       07:01     16.00       Jack       Rose
2       07:03     14.00       Alice      Bob
3       07:05     95.00       Jim        Larry
...     ...       ...         ...        ...
9999    18:16     81.00       Rose       Alice

如何从中找到“封闭成员”支付网络?

例如,如果我想查找仅包含{Rose,Alice,Jim}彼此严格进行的付款的数据子集,则以下方法可能有效:

members = ['Rose', 'Alice', 'Jim']
df_subset = df[df.seller.isin(members) & df.buyer.isin(members)]

但是,一个人如何检索最大的这样的网络呢?也就是说,不仅要为3个人,而且要为数据框中的最大人数?

我已经尝试过以下变化:

df_subset = df[df.seller.isin(df.buyer.unique())]
df_subset = df_subset[df_subset.buyer.isin(df_subset.seller.unique())]

但是,这并不成功,因为之后的df_subset.seller.unique()df_subset.buyer.unique()并不相同。

任何帮助将不胜感激。

我相信最后df_subset.seller.unique()df_subset.buyer.unique()应该相同。

3 个答案:

答案 0 :(得分:0)

这是您要寻找的最大人数

a = df[df.seller].drop_duplicates()
b = df[df.buyer].drop_duplicates()
result = pd.concat([a,b])

答案 1 :(得分:0)

IIUC,以下应做您想做的事:

common_users = set(df["buyer"]).intersection(df["seller"])
df_subset = df[df["buyer"].isin(common_users) & df["seller"].isin(common_users)]

答案 2 :(得分:0)

以下解决方案似乎有效。我将提供一个沙盒解决方案,因为它可能对其他人有用。

首先,让我们定义与问题类似的熊猫数据框:

# generates strings to be used as names, e.g.: 'hlddldxhys'
def randomString(stringLength=10):
    letters = string.ascii_lowercase
    return ''.join(random.choice(letters) for i in range(stringLength))

# let's generate a set of 600 names
participants = [];
for k in range(600):
    participants.append(randomString())

# from the generated set, draw 1000 sellers and buyers
seller = np.random.choice(participants, 1000)
buyer = np.random.choice(participants, 1000)

# construct pandas data frame
df = pd.DataFrame([seller, buyer]).T
df.columns = ['seller', 'buyer']

查看结果数据帧print(df)

     seller       buyer
----------------------------
0    bpzroghaxp  evvhhlbiys
1    qsopxbirgn  lwwljadfwg
2    cnllyrzjiz  opbvoodpgw
3    hkzafylzst  slfqtwdeak
...    ...        ...
999  natqsscnlk  ftvjvgtala

尽管有些人暗示了一个解决方案(PMende,Tal Avissar和我本人的回复),但它似乎确实有效-但只能迭代,每次df = df[df.seller.isin(df.buyer.unique()) & df.buyer.isin(df.seller.unique())]迭代时df.seller.unique()df.buyer.unique()的集合变得更加相似。重复此操作,直到它们都相同为止(请参阅最后的if语句,后跟break):

while(True):
    df = df[df.seller.isin(df.buyer.unique()) & df.buyer.isin(df.seller.unique())]
    if len(df.seller.unique()) == len(df.buyer.unique()):
        if (np.sort(df.seller.unique()) == np.sort(df.buyer.unique())).all() == True:
            break

最终检查确认df.seller.unique()df.buyer.unique()的长度相同且组成相同:

>> len(df.seller.unique()), len(df.buyer.unique())
(281, 281)

>> (np.sort(df.seller.unique()) == np.sort(df.buyer.unique())).all()
True

以下图表显示了df.seller.unique()df.buyer.unique()的集合在循环的每次迭代中如何变得彼此相似:

See also charts: visualisation of solution