清洁切片+堆叠pandas数据帧的方式

时间:2017-01-11 11:21:25

标签: python pandas dataframe slice

我有一个Pandas DataFrame,比如df,它是1099行乘33行。我需要原始文件由另一个软件处理,但它的格式不正确。这就是我试图获得大熊猫的好格式的原因。

问题非常简单:df由标识符列构成(实际情况下为7,以下示例中仅为3),然后是按月的相应结果。要清楚,它就像

A    B    C    date1result  date2result  date2result
a1   b1   c1       12           15           17
a2   b2   c3        5            8            3

但要处理,我需要每个结果有一行,为日期添加一列。在给定的示例中,它将是

A    B    C      result       date  
a1   b1   c1       12         date1 
a1   b1   c1       15         date2
a1   b1   c1       17         date3
a2   b2   c3        5         date1
a2   b2   c3        8         date2
a2   b2   c3        3         date3

更确切地说,我已经用日期手动编辑了所有列名(在read_excel之后,看起来像&01; 01/01/2015 0:00:00'或类似的东西,我无法访问它们......作为第二个问题,是否有人知道如何访问从.xlsx中的日期字段导入的列?),因此日期列名称现在为2015_01,2015_02 ... 2015_12,2016_01, ...,2016_12,第一个是'帐户','客户名称'邮政编码','段'和' Rep'。所以我尝试了以下代码:

core = df.loc[:,('Account','Customer Name','Postcode','segment','Rep')]

df_final=pd.Series([])
for year in [2015,2016]:
    for month in range(1, 13):
        label = "%i_%02i" % (year,month)
        date = []
        for i in range(core.shape[0]):
            date.append("01/%02i/%i"%(month,year))  
        df_date=pd.Series(date) #I don't know to create this 1xn df
        df_final = df_final.append(pd.concat([core, df[label], df_date], axis=1))

粗略地工作,但是非常不洁净:我得到一个(26376,30)形状的df_final,第一列是日期,然后是结果,但当然是' 2015_01'作为列名,然后是所有' 2015_02'通过' 2016_12'由NaN填写,最后是我的帐户','客户名称'邮政编码','段'和' Rep'列。有谁知道我怎么做这样的"切片+堆叠"干净利落的方式?

非常感谢。

编辑:这与此问题大致相反:Stacking and shaping slices of DataFrame (pandas) without looping

1 个答案:

答案 0 :(得分:1)

我想你需要melt

df = pd.melt(df, id_vars=['A','B','C'], value_name='result', var_name='date')
print (df)
    A   B   C         date  result
0  a1  b1  c1  date1result      12
1  a2  b2  c3  date1result       5
2  a1  b1  c1  date2result      15
3  a2  b2  c3  date2result       8
4  a1  b1  c1  date3result      17
5  a2  b2  c3  date3result       3

然后转换to_datetime

print (df)
    A   B   C  2015_01  2016_10  2016_12
0  a1  b1  c1       12       15       17
1  a2  b2  c3        5        8        3

df = pd.melt(df, id_vars=['A','B','C'], value_name='result', var_name='date')
df.date = pd.to_datetime(df.date, format='%Y_%m')
print (df)
    A   B   C       date  result
0  a1  b1  c1 2015-01-01      12
1  a2  b2  c3 2015-01-01       5
2  a1  b1  c1 2016-10-01      15
3  a2  b2  c3 2016-10-01       8
4  a1  b1  c1 2016-12-01      17
5  a2  b2  c3 2016-12-01       3