我有这样的数据框,其元素我想转换为字符串或列表的集合,并替换为空集合为无。
id super_graph sub_graph
GO1 GO1 ['GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO9
GO2 GO2 ['GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO11
GO3 GO3 ['GO1', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9'] GO12
GO4 GO4 ['GO1', 'GO6', 'GO7']
GO5 GO5 ['GO5']
GO6 GO6 ['GO1', 'GO5', 'GO7', 'GO3', 'GO9']
GO7 GO7 ['GO2', 'GO5', 'GO6', 'GO7', 'GO8', 'GO10', 'GO11', 'GO12']
GO8 GO8 ['GO2', 'GO3', 'GO4', 'GO5', 'GO6', 'GO7', 'GO8', 'GO9']
GO9 GO9
我设法分两步完成;转换列表中的字符串,然后将这些列表转换为使用它们的步骤:
initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]]#THE FRAME WHOSE EXAMPLE YOU HAVE ABOVE
initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list)| (cell is None))
list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: [l]))
list_frame2 = list_frame.applymap(lambda l: set(l) if l is not None else {})
这里的诀窍就是使用[]列表构造函数(也许我不应该使用这个在语言中具有非常特殊含义的单词但我找不到更好的单词)而不是list_frame中的list(l)因为它们的行为不同,[]将采用字符串,list()会将字符串序列分解为它们的部分。
然后我使用set()方法转换这些列表,并使用条件表达式来避免包括None(最终目标是为列的每一行添加所有三个列表(也许我可以使用更好的方法,不要'我知道,但无论如何,我想回答以下问题,进行个人启发)
我实际上打算一步完成,使用以下代码:
initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]]
initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list))
list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: {l}) if l is not None else {})
但Python不会让我喜欢我想要的:) 实际上set()方法接受列表和字符串,其行为类似于对它们的list()方法。因此,我打算使用{}来做到这一点,但它不起作用;抛出这个例外:
list_frame = initial_frame.mask(initial_frame_mask,initial_frame.applymap(lambda l: {l} if l is not None else {}))
TypeError: ("unhashable type: 'list'", 'occurred at index super_graph')
完全和
一样In [354]: l=[1,2]
In [355]: {l}
Traceback (most recent call last):
File "<ipython-input-355-37b01148d270>", line 1, in <module>
{l}
TypeError: unhashable type: 'list'
所以我相信mask方法在整体上执行向量化操作后选择数据,但是,这会触发我不应该实际看到的错误,因为我的initial_frame_mask经过精心定制以避免不方便的值。
id super_graph sub_graph
GO1 True False True
GO2 True False True
GO3 True False True
GO4 True False False
GO5 True False False
GO6 True False False
GO7 True False False
GO8 True False False
GO9 True False False
所以我想知道如何在一个步骤中执行此操作(可能使用类似的函数,它不像掩码那样,但避免从错误值开始,或使用其他方式转换它)。 我也想知道为什么list和[]的行为如此不同,我没有在Python文档中看到任何解释这是有意义的东西,以及set()和{}的同义词。 先谢谢。
快速说明:确实:list_frame2 = list_frame.applymap(lambda l:set(l)如果l不是其他没有{})因为输出而无法工作
id super_graph sub_graph
GO1 {GO1} {nan} {GO9}
GO2 {GO2} {nan} {GO11}
GO3 {GO3} {nan} {GO12}
GO4 {GO4} {nan} {nan}
GO5 {GO5} {nan} {nan}
GO6 {GO6} {nan} {nan}
GO7 {GO7} {nan} {nan}
GO8 {GO8} {nan} {nan}
GO9 {GO9} {nan} {nan}
编辑:数据帧生成器(但我认为剪贴板中有一个命令可以执行此操作,这就是我最初没有包含它的原因,抱歉;
count_frame = pd.DataFrame([["GO2","GO3","GO4","GO5","GO6","GO7","GO8","GO9"],\
[["GO4", "GO5","GO6","GO7","GO8","GO9"],
["GO4", "GO5","GO6","GO7","GO8","GO9"],
["GO1", "GO5","GO6","GO7","GO8","GO9"],
["GO1", "GO6","GO7"],
["GO5"]
["GO1", "GO5","GO7","GO3","GO9"],
["GO2", "GO5","GO6","GO7","GO8","GO10","GO11", "GO12"],
["GO2", "GO3","GO4","GO5","GO6","GO7","GO8","GO9"],
],\
["GO9","GO11","GO12"]], index = ['id','super_graph','sub_graph'], columns=["GO1","GO2","GO3","GO4","GO5","GO6","GO7","GO8","GO9","]).T
答案 0 :(得分:1)
您可以跳过屏蔽步骤直接进行映射。
实际上,通过引入以下一行,我觉得你创造了自己的问题。
initial_frame_mask = ~initial_frame.applymap(lambda cell: isinstance(cell, list))
这引入了一个掩码,对于所有列表都是False,因此对于super_graph
的几乎所有元素都是如此,但对于其他元素所发生的事情并不是完全透明的。
在一行代码中实现您想要的目标:
initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]]
initial_frame.applymap(lambda l: {*l} if isinstance(l, list) else {l})
编辑:如果你不希望&#34;无&#34;要显示在数据框中,您可以先使用方便的值替换这些值。
initial_frame.fillna('').applymap(lambda l: {*l} if isinstance(l, list) else {l})
EDIT2:Hacky解决方案,以获取具有独特项目的列表(也可以作为oneliner,但认为这已经足够复杂):
initial_frame['ss'] = initial_frame.fillna('').applymap(lambda l: [*l] if isinstance(l, list) else []).values.sum(axis=1)
initial_frame['ss'].apply(lambda x: list(filter(None,{*x})))