有没有办法在Python中使用融合函数多列?

时间:2016-05-24 19:40:32

标签: python pandas melt

我有一个交叉表格式的表格,例如:

State   Item #  x1  x2  x3  y1  y2  y3  z1  z2  z3
CA      1       6   4   3   7   5   3       11      5       1
CA      2       7   3   1   15  10  5       4       2       1
FL      3       3   2   1   5   3   2       13      7       2
FL      4       9   4   2   16  14  12      14      5       4

我正在尝试使用融合功能将数据放入以下格式:

State   Item #  x   xvalue  y   yvalue  z   zvalue
CA      1       x1    6     y1    7     z1    11
CA      1       x2    4     y2    5     z2    5
CA      1       x3    3     y3    3     z3    1
CA      2       x1    7     y1    15    z1    4
CA      2       x2    3     y2    10    z2    2
CA      2       x3    1     y3    5     z3    1    

我知道如何使用融合函数来执行其中一个值,例如x。但我也不知道如何用y和z做到这一点。请参阅下面的代码,仅执行x代码。有没有办法我可以调整这个来为y和z做呢?或者我应该尝试为x,y和z分别使用熔解函数,然后以某种方式将它们组合起来?

df_m = pd.melt(df, id_vars=['State', 'Item #'],
           value_vars=['x1','x2','x3'],
           var_name='x', value_name='xvalue')

3 个答案:

答案 0 :(得分:1)

我不这么认为,但你可以使用两行解决方案:

values = [['x1','x2','x3'], ['y1', 'y2', 'y3'], ['z1', 'z2', 'z3']]

df_m = pd.concat([pd.melt(df, id_vars=['State', 'Item_#'], value_vars=val, var_name='var', value_name='value') for val in values])

pd.concat函数是一种强大的(即快速)方式来垂直堆叠DataFrame。

答案 1 :(得分:1)

这是一个不使用melt但适用于任意数量的xyz'组的版本。

import pandas as pd
from io import StringIO

df = pd.read_csv(StringIO('''
    State   ItemN  x1  x2  x3  y1  y2  y3  z1  z2  z3
CA      1       6   4   3   7   5   3       11      5       1
CA      2       7   3   1   15  10  5       4       2       1
FL      3       3   2   1   5   3   2       13      7       2
FL      4       9   4   2   16  14  12      14      5       4'''),
sep=r' +')

# prepare index
df = df.set_index(list(df.columns[:2]))
df.columns = pd.MultiIndex.from_tuples([(c[0], c) for c in df.columns])

#              x         y           z      
#             x1 x2 x3  y1  y2  y3  z1 z2 z3
# State ItemN                               
# CA    1      6  4  3   7   5   3  11  5  1
#       2      7  3  1  15  10   5   4  2  1
# FL    3      3  2  1   5   3   2  13  7  2
#       4      9  4  2  16  14  12  14  5  4


# stack and concat each 'group'
df2 = pd.concat((
    df[c].stack().reset_index(-1)
    for c in df.columns.levels[0]),
    axis=1)

# rename the columns
new_cols = [None for _ in range(df2.shape[1])]
new_cols[::2]  = [c for c in df.columns.levels[0]]
new_cols[1::2] = [c + 'value' for c in df.columns.levels[0]]

df2.columns = new_cols

#               x  xvalue   y  yvalue   z  zvalue
# State ItemN                                    
# CA    1      x1       6  y1       7  z1      11
#       1      x2       4  y2       5  z2       5
#       1      x3       3  y3       3  z3       1
#       2      x1       7  y1      15  z1       4
#       2      x2       3  y2      10  z2       2
#       2      x3       1  y3       5  z3       1
# FL    3      x1       3  y1       5  z1      13
#       3      x2       2  y2       3  z2       7
#       3      x3       1  y3       2  z3       2
#       4      x1       9  y1      16  z1      14
#       4      x2       4  y2      14  z2       5
#       4      x3       2  y3      12  z3       4

答案 2 :(得分:0)

pd.wide_to_long怎么办?

# Make dataframe
df = pd.DataFrame({'State' : ['CA']*2 + ['FL']*2,
                   'Item' : [1, 2, 3, 4],
                   'x1' : [6, 7, 3, 9],
                   'x2' : [4, 3, 2, 4],
                   'x3' : [3, 1, 1, 2],
                   'y1' : [7, 15, 5, 16],
                   'y2' : [5, 10, 3, 14],
                   'y3' : [3, 5, 2, 12],
                   'z1' : [11, 4, 13, 14],
                   'z2' : [5, 2, 7, 5],
                   'z3' : [1, 1, 2, 4]})

# Make final dataframe using pd.wide_to_long
final = pd.wide_to_long(df,
                        stubnames = ['x', 'y', 'z'],
                        i = ['State',
                             'Item'],
                        j = 'number').reset_index()

# Show final dataframe
final

wide_to_long

我知道返回的数据框看起来与您请求的数据帧完全不同,但它仍然可以正常工作。实际上,它现在将您的x,y,z,xvalue,yvalue和zvalue列组合成x,y,z和一个'数字'用于引用第一,第二和第三值的列。