使用掩码和 error/incompatibilities 在数据框中进行类型转换
Type conversion in dataframe using mask and error/incompatibilities
我有这样的数据框,我想将其元素转换为字符串或列表的集合,并用 None.
的空集合替换
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(l) =42=] 创建,因为它们的行为不同,[] 将采用这样的字符串,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'
所以我相信掩码方法在整体上执行向量化操作后选择数据,但是因此,这触发了这个我实际上不应该看到的错误,因为我的 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) if l is not None else {}) 不会工作,因为它输出
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
您可以跳过遮罩步骤,直接进行映射。
实际上,通过引入以下行,我觉得你自己制造了问题。
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})
编辑:如果您不希望 "None" 出现在您的数据框中,您可以先用方便的值替换这些值。
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})))
我有这样的数据框,我想将其元素转换为字符串或列表的集合,并用 None.
的空集合替换 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(l) =42=] 创建,因为它们的行为不同,[] 将采用这样的字符串,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'
所以我相信掩码方法在整体上执行向量化操作后选择数据,但是因此,这触发了这个我实际上不应该看到的错误,因为我的 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) if l is not None else {}) 不会工作,因为它输出
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
您可以跳过遮罩步骤,直接进行映射。
实际上,通过引入以下行,我觉得你自己制造了问题。
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})
编辑:如果您不希望 "None" 出现在您的数据框中,您可以先用方便的值替换这些值。
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})))