代码之家  ›  专栏  ›  技术社区  ›  Riccardo Bucco

将单个数据帧行分解为多个数据帧行

  •  3
  • Riccardo Bucco  · 技术社区  · 3 年前

    我的数据帧有一些列,其中每个值可以是“1”、“2”、“3”或“任意”。举个例子:

    >>> df = pd.DataFrame({'a': ['1', '2', 'any', '3'], 'b': ['any', 'any', '3', '1']})
    >>> df
         a    b
    0    1  any
    1    2  any
    2  any    3
    3    3    1
    

    在我的例子中,“any”表示值可以是“1”、“2”或“3”。我想只使用值“1”、“2”和“3”(或者,通常,我可能有的任何值列表)来生成所有可能的行。下面是上述示例的预期输出:

       a  b
    0  1  1
    1  1  2
    2  1  3
    3  2  1
    4  2  2
    5  2  3
    6  3  3
    7  3  1
    

    我用这种丑陋而复杂的方法得到了这个结果:

    a = df['a'].replace('any', '1,2,3').apply(lambda x: eval(f'[{str(x)}]')).explode()
    result = pd.merge(df.drop(columns=['a']), a, left_index=True, right_index=True)
    b = result['b'].replace('any', '1,2,3').apply(lambda x: eval(f'[{str(x)}]')).explode()
    result = pd.merge(result.drop(columns=['b']), b, left_index=True, right_index=True)
    result = result.drop_duplicates().reset_index(drop=True)
    

    1 回复  |  直到 3 年前
        1
  •  3
  •   Quang Hoang    3 年前

    可以替换字符串 any 例如。 '1,2,3'

    (df.replace('any', '1,2,3')
       .apply(lambda x: x.str.split(',') if x.name in ['a','b'] else x)
       .explode('a').explode('b')
       .drop_duplicates(['a','b'])
    )
    

    输出:

       a  b  c
    0  1  1  1
    0  1  2  1
    0  1  3  1
    1  2  1  1
    1  2  2  1
    1  2  3  1
    2  3  3  1
    3  3  1  1
    
        2
  •  1
  •   Eelco van Vliet    3 年前

    我不会使用eval和字符串操作,而只是用一组值替换任何值

    df[df == 'any'] = {1, 2, 3}
    for col in df:
        df = df.explode(col)
    df = df.astype(int).drop_duplicates()
    

    print(df)
       a  b
    0  1  1
    0  1  2
    0  1  3
    1  2  1
    1  2  2
    1  2  3
    2  3  3
    3  3  1