Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用掩码和错误/不兼容在数据帧中进行类型转换_Python_Pandas_Dataframe_Type Conversion_Mask - Fatal编程技术网

Python 使用掩码和错误/不兼容在数据帧中进行类型转换

Python 使用掩码和错误/不兼容在数据帧中进行类型转换,python,pandas,dataframe,type-conversion,mask,Python,Pandas,Dataframe,Type Conversion,Mask,我有这样的dataframe,对于那些是字符串或列表的元素,我希望将其转换为集合,对于那些没有的元素,我希望将其替换为空集合 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',

我有这样的dataframe,对于那些是字符串或列表的元素,我希望将其转换为集合,对于那些没有的元素,我希望将其替换为空集合

    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),因为它们的行为不同,[]将取一个字符串,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,但避免以坏值开始,或者使用另一种方法来转换)。 我还想知道为什么list和[]的行为如此不同,我在Python文档中没有看到任何解释这一点的内容,idem表示set()和{}。 提前谢谢

Quicknote:确实:list_frame2=list_frame.applymap(lambda l:set(l)如果l不是None-other{})将不起作用,因为它输出

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}
编辑:DataFrameGenerator(但我认为剪贴板中有一个命令可以这样做,这就是为什么我一开始没有包括它,对不起

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))
这引入了一个掩码,该掩码对于所有列表都是假的,因此对于
super\u graph
的几乎所有元素,但对于其他元素所发生的事情并不是完全透明的

要实现您似乎想要的,只需一行代码:

initial_frame = count_frame.loc[:,['id', "super_graph", "sub_graph"]] 
initial_frame.applymap(lambda l: {*l} if isinstance(l, list) else {l})
编辑:如果您不希望“无”出现在您的数据框中,您可以先用一个方便的值替换这些值

initial_frame.fillna('').applymap(lambda l: {*l} if isinstance(l, list) else {l})
EDIT2:获取具有唯一项的列表的黑客解决方案(也可以作为一行程序来完成,但我认为这已经足够复杂了):


你能提供一种生成输入数据帧的方法吗?目前还不清楚
数据类型是什么。你是否尝试过使用
{*l}
而不是仅仅使用
{l}
?这将是一个很好的调用,但它会将字符串分开。无论如何,我最后继续处理列表,然后对它们求和,然后将它们转换为集合(我有一个错误,使用if None then{}将None替换为dicts,但是无论如何,编写if None then set()不会改变任何东西,sum也不能很好地处理集合…)问题是,我不想在集合中包含None,因为消除它们会很繁琐,但我想我可以用initial_frame.applymap(lambda l:{*l}如果l不是else None如果l是Instance(l,list)else{l})来实现这一点。另外,我意识到我不能用列表的方式来总结集合(working_series=list_frame.sum(axis=1)),所以我在列表上完全这样做,然后使用working_series.map(set)(否则我有一个集合的总和,它只是浮动的,奇怪的是,而对于列表来说一切都很好)。无论如何,我都会接受你的答案,因为你已经回答了这个问题。如果你想去掉Nones,你可以做
initial_frame.fillna(“”)
。至于轴1上的和,这可能会产生可怕的结果,沿着
{'GO3'}{
等等。或者只是浮动64s
0
。是的,事实上,我把“无”部分弄错了,我想用列表填充NA,但不可能,所以我试着在之后替换它们(我没有想到字符串替换,我对此很愚蠢,因为我还是替换了字符串).对于求和部分,我添加的调用不会比求和列表更好,因为对于集合,它不起作用,而且我想要一些灵活的东西,不必指定索引、标签或循环或其他任何东西。所以我想对于列表,它应该是可以的。每次解包的效率不会比使用掩码低吗?我想这是一个问题这是一个很好的解决方案;虽然我对结果不太确定;我用我认为是你想要的东西再次编辑了,但这是一个相当粗糙的解决方案,感觉不太理想。你当然可以用
set(filter(…)
或其他iterables替换
list(filter(…)
。谢谢。filter确实可以做到这一点。
initial_frame.fillna('').applymap(lambda l: {*l} if isinstance(l, list) else {l})
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})))