干净的切片方式 + 堆叠 pandas 数据框
Clean way of slicing + stacking pandas dataframe
我有一个 Pandas DataFrame,比如说 df,它有 1099 行 x 33 行。我需要用另一个软件处理原始文件,但它的格式不正确。这就是为什么我试图获得 pandas.
的良好格式
问题很简单: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/2015 0:00:00' 或类似的东西,并且我无法访问它们...作为次要问题,有人知道如何访问从 .xlsx 中的日期字段导入的列吗?),因此日期列名称现在为 2015_01、2015_02... 2015_12, 2016_01, ..., 2016_12, 第 5 个是 'Account','Customer Name','Postcode','segment' 和 '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 填充,最后是我的帐户', 'Customer Name', 'Postcode', 'segment' 和 'Rep' 列。有谁知道我如何以干净的方式完成这样的 "slicing+stacking"?
非常感谢。
编辑:大致是这个问题的反面:Stacking and shaping slices of DataFrame (pandas) without looping
我想你需要 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
我有一个 Pandas DataFrame,比如说 df,它有 1099 行 x 33 行。我需要用另一个软件处理原始文件,但它的格式不正确。这就是为什么我试图获得 pandas.
的良好格式问题很简单: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/2015 0:00:00' 或类似的东西,并且我无法访问它们...作为次要问题,有人知道如何访问从 .xlsx 中的日期字段导入的列吗?),因此日期列名称现在为 2015_01、2015_02... 2015_12, 2016_01, ..., 2016_12, 第 5 个是 'Account','Customer Name','Postcode','segment' 和 '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 填充,最后是我的帐户', 'Customer Name', 'Postcode', 'segment' 和 'Rep' 列。有谁知道我如何以干净的方式完成这样的 "slicing+stacking"?
非常感谢。
编辑:大致是这个问题的反面:Stacking and shaping slices of DataFrame (pandas) without looping
我想你需要 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