Python 将某些列转换为行

Python 将某些列转换为行,python,pandas,Python,Pandas,因此,我的数据集有n个日期的位置信息。问题是每个日期实际上都是不同的列标题。例如,CSV看起来像 location name Jan-2010 Feb-2010 March-2010 A "test" 12 20 30 B "foo" 18 20 25 我想让它看起来像 location name Date Value A

因此,我的数据集有n个日期的位置信息。问题是每个日期实际上都是不同的列标题。例如,CSV看起来像

location    name    Jan-2010    Feb-2010    March-2010
A           "test"  12          20          30
B           "foo"   18          20          25
我想让它看起来像

location    name    Date        Value
A           "test"  Jan-2010    12       
A           "test"  Feb-2010    20
A           "test"  March-2010  30
B           "foo"   Jan-2010    18       
B           "foo"   Feb-2010    20
B           "foo"   March-2010  25

问题是我不知道该列中有多少个日期(尽管我知道它们总是在名称之后开始)

更新
从v0.20开始,
melt
是一个一阶函数,您现在可以使用

df.melt(id_vars=["location", "name"], 
        var_name="Date", 
        value_name="Value")

  location    name        Date  Value
0        A  "test"    Jan-2010     12
1        B   "foo"    Jan-2010     18
2        A  "test"    Feb-2010     20
3        B   "foo"    Feb-2010     20
4        A  "test"  March-2010     30
5        B   "foo"  March-2010     25


旧版本:我想我找到了一个更简单的解决方案

temp1 = pd.melt(df1, id_vars=["location"], var_name='Date', value_name='Value')
temp2 = pd.melt(df1, id_vars=["name"], var_name='Date', value_name='Value')
将整个
temp1
temp2
的列
name

temp1['new_column'] = temp2['name']
你现在得到了你想要的

您可以在年份列中添加前缀,然后直接馈送到
pd.wide\u to\u long
。我不会假装这是有效的,但在某些情况下,它可能比,例如,当您的列已经有一个适当的前缀时更方便

df.columns = np.hstack((df.columns[:2], df.columns[2:].map(lambda x: f'Value{x}')))

res = pd.wide_to_long(df, stubnames=['Value'], i='name', j='Date').reset_index()\
        .sort_values(['location', 'name'])

print(res)

   name        Date location  Value
0  test    Jan-2010        A     12
2  test    Feb-2010        A     20
4  test  March-2010        A     30
1   foo    Jan-2010        B     18
3   foo    Feb-2010        B     20
5   foo  March-2010        B     25
用于
多索引系列
,然后用于
数据帧
添加
重命名

df1 = (df.set_index(["location", "name"])
         .stack()
         .reset_index(name='Value')
         .rename(columns={'level_2':'Date'}))
print (df1)
  location  name        Date  Value
0        A  test    Jan-2010     12
1        A  test    Feb-2010     20
2        A  test  March-2010     30
3        B   foo    Jan-2010     18
4        B   foo    Feb-2010     20
5        B   foo  March-2010     25

添加一个可复制的笔记本链接,使用以下方法演示@DMS的答案:


@DSM此函数的反方向是什么。i、 e.如何将
df2
[返回]转换为
df
@3kstc。你想看看枢轴。可能是
pandas.pivot\u表(df2,values='Value',index=['location','name'],columns='Date')。reset\u index()
@DSM有什么方法可以倒退吗?这意味着我有许多行的名称相同,我希望所有的日期都不同columns@Adrian您可以在df操作中取消熔化/反向熔化(也称为旋转)。有关更多详细信息,请查看此
df1 = (df.set_index(["location", "name"])
         .stack()
         .reset_index(name='Value')
         .rename(columns={'level_2':'Date'}))
print (df1)
  location  name        Date  Value
0        A  test    Jan-2010     12
1        A  test    Feb-2010     20
2        A  test  March-2010     30
3        B   foo    Jan-2010     18
4        B   foo    Feb-2010     20
5        B   foo  March-2010     25
df.melt(id_vars=["location", "name"], 
    var_name="date", 
    value_name="value")