合并列时如何保留所有唯一的值组合?

Posted

技术标签:

【中文标题】合并列时如何保留所有唯一的值组合?【英文标题】:How to preserve all unique combinations of values when merging columns? 【发布时间】:2018-03-12 22:13:10 【问题描述】:

给定表格

| A | B | C | C | C | D | D |
  1   0   x   y   z   8   9
  2   4   x   b               

什么是最好的返回方法

| A | B | C | D |
  1   0   x   8
  1   0   y   8
  1   0   z   8
  1   0   x   9
  1   0   y   9
  1   0   z   9
  2   4   x
  2   4   b

我正在使用 pandas read_csv 从 csv 中提取...不确定我是否可以在那里处理它,或者使用 SQL,或者使用 Python dicts。

苦苦搜索,找不到答案。

(我是新手,所以我可能会遗漏一些基本的东西......)

编辑:需要容纳 n

【问题讨论】:

【参考方案1】:
import pandas as pd

df = pd.DataFrame([[1,0,'x','y','z',8,9]], columns=list('ABCCCDD'))

result = pd.MultiIndex.from_product(
             [grp for key, grp in df.T.groupby(level=0)[0]]).to_frame(index=False)
print(result)

产量

   0  1  2  3
0  1  0  x  8
1  1  0  x  9
2  1  0  y  8
3  1  0  y  9
4  1  0  z  8
5  1  0  z  9

如果您的 DataFrame 有多于一行:

import numpy as np
import pandas as pd

def row_to_arrays(row, idx):
    """
    Split a row into a list of component arrays.
    idx specifies the indices at which we want to split the row
    """
    # Use row[1:] because the first item in each row is the index 
    # (which we want to ignore)
    result = np.split(row[1:], idx)
    # Filter out empty strings
    result = [arr[arr != ''] for arr in result]
    # Filter out empty arrays
    result = [arr for arr in result if len(arr)]
    return result

def arrays_to_dataframe(arrays):
    """
    Convert list of arrays to product DataFrame
    """
    return pd.MultiIndex.from_product(arrays).to_frame(index=False) 

def df_to_row_product(df):
    # find the indices at which to cut each row
    idx = pd.DataFrame(df.columns).groupby(0)[0].agg(lambda x: x.index[0])[1:]
    data = [arrays_to_dataframe(row_to_arrays(row, idx))
            for row in df.itertuples()]
    result = pd.concat(data, ignore_index=True).fillna('')
    return result

df = pd.DataFrame([[1,0,'x','y','z',8,9],
                   [2,4,'x','b','','','']], columns=list('ABCCCDD'))

print(df_to_row_product(df))

产量

   0  1  2  3
0  1  0  x  8
1  1  0  x  9
2  1  0  y  8
3  1  0  y  9
4  1  0  z  8
5  1  0  z  9
6  2  4  x   
7  2  4  b   

【讨论】:

可以做到pd.MultiIndex.from_product([g.values[0] for k, g in df.groupby(level=0, axis=1)]).to_frame(index=False) 无需外部转置。 所以这很有趣,但我们丢失了标题名称。此外,我仍然无法让它为我的其他数据集工作......结果仅显示来自具有 3 个唯一列和 61 行的数据集的 3 行和 2 列。 ...您能否提供一个多行版本,以便更轻松地进行故障排除? 我想我看到了问题,我的示例给出了单行,但我需要容纳多行数据(问题已更新)【参考方案2】:

我可以想到一种可能的解决方案,使用一点预处理和itertools.product

from itertools import product 

prod = list(product(*df.groupby(df.columns, axis=1)\
                  .apply(lambda x: x.values.reshape(-1, )).tolist()))
prod
[(1, 0, 'x', 8),
 (1, 0, 'x', 9),
 (1, 0, 'y', 8),
 (1, 0, 'y', 9),
 (1, 0, 'z', 8),
 (1, 0, 'z', 9)]

df = pd.DataFrame(prod, columns=list('ABCD'))\
                 .sort_values('D').reset_index(drop=1)
df
   A  B  C  D
0  1  0  x  8
1  1  0  y  8
2  1  0  z  8
3  1  0  x  9
4  1  0  y  9
5  1  0  z  9

【讨论】:

我想将 ['A','B'] 设置为索引,然后应用笛卡尔。这个不错 在 prod= 行上获取带有完整数据集的 SegFault @uxmatthew 您必须有很多列,在这种情况下,这可能对您没有帮助。道歉。

以上是关于合并列时如何保留所有唯一的值组合?的主要内容,如果未能解决你的问题,请参考以下文章

Pandas加入(合并?)数据帧,只保留唯一的指标

保留数据框中的行,对于某些列的值的所有组合,在另一列中包含相同的元素

隐藏前一列时如何保留列的位置?

使用 python,我如何从 csv 中获取唯一行,但获取合并了哪些行(或行中的值)的记录?

如何链接多个组合框表中的两个组合框?

如何在 groupby 2 列之后保留 DataFrame 的原始索引?