我一直在纠结这个问题,感觉有点卡。
我有一个数据框架,由这样的数据组成,名为 merged_frames
(它是一个单一的框架,通过连接一些具有相同形状的框架来创建)。
fqdn source
0 site1.org public_source_a
1 site2.org public_source_a
2 site3.org public_source_a
3 site1.org public_source_b
4 site4.org public_source_b
5 site1.org public_source_b
6 site4.org public_source_d ...
7 site1.org public_source_c
...
我想做的是在这个框架中创建一个新的列,其中包含一个列表(最好是一个Python列表,而不是一个以命令分隔的字符串),其中包含按 fqdn
值。例如,为 fqdn
价值 site1.org
根据这个示例数据,应该是这样的(这只是我所期望的一个子集,还应该有其他的记录 fqdn
价值)
fqdn source_list source
site1.org [public_source_a, public_source_b, public_source_c] public_source_a
site1.org [public_source_a, public_source_b, public_source_c] public_source_b
site1.org [public_source_a, public_source_b, public_source_c] public_source_c
site1.org [public_source_a, public_source_b, public_source_c] public_source_d
一旦我有了这个表格中的数据,我就会简单地在表格中放入 source
列,然后使用 drop_duplicates(keep='first')
以摆脱所有,但一个。
我挖出了一些两年前用来做类似事情的旧代码,但它没有按照我的预期工作。我已经很久没有用Pandas做这样的事情了。我当时的情况是这样的。
merged_frame['source_list'] = merged_frame.groupby(
'fqdn', as_index=False)[['source']].aggregate(
lambda x: list(x))['source']
它的行为非常奇怪 虽然事实上它正在创建 source_list
作为一个listarray,列中的数据是不正确的。此外,不少 fqdn
的值有一个nullNaN值 source_list
我有一种感觉,这个我需要用完全不同的方法。如果能得到一点帮助,我将非常感激,我现在完全被封锁了,并且没有取得任何进展,尽管有我认为非常相关的示例代码块,我在一个类似的数据集上使用。
EDIT:
我已经取得了一点进展,只是从基本原理开始,有了下面的内容,虽然这是把字符串连接在一起,而不是让它们成为一个列表。
merged_frame['source_list'] = merged_frame.groupby('fqdn').source.transform(','.join)
我很确定用一个简单的 apply
在这里,我可以把他们分成一个 list
. 但是,什么是正确的方式来做到这一点在一个镜头,所以我不需要做不必要的。join
然后 apply(split(','))
?
从上面的例子中创建数据帧。
df=pd.DataFrame({'fqdn':['site1.org','site2.org','site3.org','site1.org','site4.org','site1.org','site4.org','site1.org'],\
'source':['public_source_a','public_source_a','public_source_a','public_source_b','public_source_b','public_source_b',\
'public_source_d','public_source_c']})
使用groupby和apply(list)
df_grouped=df.groupby('fqdn')['source'].unique().apply(list).reset_index()
与原数据集合并,并重新命名列。
result=pd.merge(df,df_grouped,on='fqdn',how='left')
result.rename(columns={'source_x':'source','source_y':'source_list'},inplace=True)