为了账号安全,请及时绑定邮箱和手机立即绑定

根据列表过滤列表的熊猫列

根据列表过滤列表的熊猫列

隔江千里 2021-08-05 15:18:00
有一个大的DataFrame如下:userid    user_mentions1         [2, 3, 4]1         [3]2         NaN2         [1,3]3         [1,4,5]3         [4]该user_mentions栏目是名单userid已经由每一个用户提到秒。例如,第一行的意思是:用户 1 提到了用户 2、3 和 4。我需要在userid列中的用户之间创建一个提及网络。也就是说,我想要userid列中每个用户被列中其他用户提及的次数userid。所以基本上,首先我需要这样的东西:filtered = df[df['user_mentions'].isin(df['userid'].unique())]但这对一列列表不起作用。如果我解决了上述问题,那么我可以groupby['userid','user_mentions']。编辑最终输出应该是:Source    Target    Number1         2         11         3         22         1         12         3         13         1         13         5         1
查看完整描述

3 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

这不是一项非常适合 Pandas / NumPy 的任务。所以我建议你使用collections.defaultdict创建一个计数字典,然后从字典中构建一个数据框:


from collections import defaultdict


dd = defaultdict(lambda: defaultdict(int))


for row in df.itertuples(index=False):

    vals = row.user_mentions

    if vals == vals:

        for val in vals:

            dd[row.userid][val] += 1


df = pd.DataFrame([(k, w, dd[k][w]) for k, v in dd.items() for w in v],

                  columns=['source', 'target', 'number'])


print(df)


   source  target  number

0       1       2       1

1       1       3       2

2       1       4       1

3       2       1       1

4       2       3       1

5       3       1       1

6       3       4       2

7       3       5       1

当然,您不应该首先将列表放在 Pandas 系列中。这是一个嵌套的指针层,应该尽可能避免。


查看完整回答
反对 回复 2021-08-05
?
慕斯709654

TA贡献1840条经验 获得超5个赞

根据您的编辑,我将不得不同意@jpp。


对于您的(未经编辑的)原始问题,在收集每个用户的提及次数方面,您可以执行以下操作:


df['counts'] = df['userid'].apply(lambda x: df['user_mentions'].dropna().sum().count(x))


df[['userid','counts']].groupby('userid').first()

产量:


        counts

userid        

1            2

2            1

3            3


查看完整回答
反对 回复 2021-08-05
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

这是一种方法。


# Remove the `NaN` rows

df = df.dropna()


# Construct a new DataFrame

df2 = pd.DataFrame(df.user_mentions.tolist(), 

                   index=df.userid.rename('source')

                  ).stack().astype(int).to_frame('target')


# Groupby + size

df2.groupby(['source', 'target']).size().rename('counts').reset_index()


   source  target  counts

0       1       2       1

1       1       3       2

2       1       4       1

3       2       1       1

4       2       3       1

5       3       1       1

6       3       4       2

7       3       5       1


查看完整回答
反对 回复 2021-08-05
  • 3 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信