Python 熊猫分解并删除多个列的重复项

Python 熊猫分解并删除多个列的重复项,python,pandas,Python,Pandas,我在尝试对多个4列执行explode时遇到一些问题。第一个问题是,如果我试图同时分解所有列,就会遇到MemoryError。分解每个列后会有许多重复项,因此我可以使用drop_duplicates,但是由于列中有列表,因此会引发TypeError:unhabable type:'list'。如果我使用astypestr将列转换为字符串,则这些列不能与.explode一起使用。因此,如果在执行第二个.explode之前尝试对列进行pd.eval,则会得到UndefinedVariableError

我在尝试对多个4列执行explode时遇到一些问题。第一个问题是,如果我试图同时分解所有列,就会遇到MemoryError。分解每个列后会有许多重复项,因此我可以使用drop_duplicates,但是由于列中有列表,因此会引发TypeError:unhabable type:'list'。如果我使用astypestr将列转换为字符串,则这些列不能与.explode一起使用。因此,如果在执行第二个.explode之前尝试对列进行pd.eval,则会得到UndefinedVariableError:未定义名称“nan”。以下是示例数据集:

    id     col_1      col_2   col_3   col_4 
0    1 ['a','b']        nan   ['c']     nan   
1    2       nan  ['d','e']     nan     nan
2    3     ['f']        nan     nan     nan
3    4       nan      ['g']     nan     nan 
4    5       nan        nan   ['h']     nan
5    6       nan        nan   ['i']   ['j'] 
这是当前代码:

for i in new_table:
    new_table = new_table.explode(i)
    new_table = new_table.astype(str)
    new_table = new_table.drop_duplicates()
    new_table['col_1'] = pd.eval(new_table['col_1'])
    new_table['col_2'] = pd.eval(new_table['col_2'])
    new_table['col_3'] = pd.eval(new_table['col_3'])
    new_table['col_4'] = pd.eval(new_table['col_4'])
pd.eval引发UndefiniedVariableError:未定义名称“nan”。如果删除最后4行,则列将被解释为字符串,在第二个循环中,分解不会执行任何操作,因为输入是字符串,而不是列表。但是,我必须将列转换为字符串以执行drop_重复

用于重新创建示例数据集的代码:

new_table = pd.DataFrame({'id':[1,2,3,4,5,6],
                          'col_1':[['a','b'],np.nan,['f'],np.nan,np.nan,np.nan],
                          'col_2':[np.nan,['d','e'],np.nan,['g'],np.nan,np.nan],
                          'col_3':[['c'],np.nan,np.nan,np.nan,['h'],['i']],
                          'col_4':[np.nan,np.nan,np.nan,np.nan,np.nan,['j']]})
预期产出:

id     col_1      col_2   col_3   col_4 
1          a        nan       c     nan
1          b        nan       c     nan
2        nan          d     nan     nan
2        nan          e     nan     nan
3          f        nan     nan     nan
4        nan          g     nan     nan
5        nan        nan       h     nan
6        nan        nan       i       j

你能不能这样说:

df[['id']].join((df[i].explode() for i in df.iloc[:,1:]))
输出:

|    |   id | col_1   | col_2   | col_3   | col_4   |
|---:|-----:|:--------|:--------|:--------|:--------|
|  0 |    1 | a       | nan     | c       | nan     |
|  0 |    1 | b       | nan     | c       | nan     |
|  1 |    2 | nan     | d       | nan     | nan     |
|  1 |    2 | nan     | e       | nan     | nan     |
|  2 |    3 | f       | nan     | nan     | nan     |
|  3 |    4 | nan     | g       | nan     | nan     |
|  4 |    5 | nan     | nan     | h       | nan     |
|  5 |    6 | nan     | nan     | i       | j       |
注意,我认为您正在做的和我正在做的主要区别在于,您正在数据帧上使用explode,因此您的数据帧对于您调用的每个列都是重复的。然后只选择分解的列A并加入新的数据帧

我正在做的是分解每个columnpd.Series,并将分解后的每个Series的结果在索引上连接在一起。我不是在数据帧上使用explode时创建一堆额外的列。

我有另一种方法使用stack,然后explode,cumcount和unstack,我想您可以试试

s= new_table.set_index('id').stack(dropna=True).explode().to_frame('s')
final = (s.set_index(s.groupby(s.index.get_level_values(-1))
                              .cumcount(),append=True)['s'].unstack(1))
final = final.groupby(level=0).apply(lambda x: 
                      x.ffill().bfill()).drop_duplicates().droplevel(1)

它们是真实的列表而不是列表的str repr吗?如果是,您可以发布代码来重新创建数据帧吗?此外,预期的产出也会有所帮助。谢谢:是的,它们是真实的列表。正在编辑。。。唯一需要记住的是,这些列表包含2个以上的项,并且有超过30000行,因此分解所有列会生成memoryerror。好吧,这不会删除重复项,因为我遇到了51M多行,但是它不会生成MemoryError,所以应该可以在上面执行drop_复制。我不会在整个数据帧上爆炸。通过使用循环,我将在每个列系列上单独展开,在任何一个解决方案中都不会添加额外的列。这将在您和我的解决方案上生成重复的行,需要在每次执行后立即删除这些行。否则,数据帧的大小将变得无法管理。drop_duplicates已运行超过15分钟。在每次分解后使用drop_duplicates可确保数据帧保持健康的大小。df.ExplodeColumnName生成具有额外列的新数据帧。现在s.explode,其中s是一个pd。级数只生成该列和索引。看到区别了吗?如果您将循环修改为使用df['columnname'].explode,我认为这会减少内存使用。您确定吗?我在文档、示例中以及在较小的文件上运行时,都没有找到任何关于额外列的内容。不过,是的,我同意内存使用情况,因为您的代码确实运行了,而我的代码生成了内存错误。没问题。快乐编码!谢谢你,安基!后来使用stack、explode、groupby和lambda的性能让我非常害怕。“不过它确实起作用了。”我理解塞利乌斯廷格。我希望找到一种没有for循环的方法。我同意这是一个实验性的答案,但无法避免lambda,因为每组都需要ffill和bfill
print(final)

    col_1 col_2 col_3 col_4
id                        
1      a   NaN     c   NaN
1      b   NaN     c   NaN
2    NaN     d   NaN   NaN
2    NaN     e   NaN   NaN
3      f   NaN   NaN   NaN
4    NaN     g   NaN   NaN
5    NaN   NaN     h   NaN
6    NaN   NaN     i     j