我的数据集有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

我的问题是,我不知道有多少日期在列(虽然我知道他们总是开始后的名字)


当前回答

添加一个你可以复制的笔记本的链接,用pandas.melt演示@DMS的答案:

df.melt(id_vars=["location", "name"], 
    var_name="date", 
    value_name="value")

https://deepnote.com/@DataScience/Unpivot-a-DataFrame-from-wide-to-long-format-lN7WlqOdSlqroI_7DGAkoA

其他回答

更新 从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

旧版本: <0.20

你可以用pd。融化到大部分地方,然后排序:

>>> df
  location  name  Jan-2010  Feb-2010  March-2010
0        A  test        12        20          30
1        B   foo        18        20          25
>>> df2 = pd.melt(df, id_vars=["location", "name"], 
                  var_name="Date", value_name="Value")
>>> df2
  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
>>> df2 = df2.sort(["location", "name"])
>>> df2
  location  name        Date  Value
0        A  test    Jan-2010     12
2        A  test    Feb-2010     20
4        A  test  March-2010     30
1        B   foo    Jan-2010     18
3        B   foo    Feb-2010     20
5        B   foo  March-2010     25

(可能想要抛出一个.reset_index(drop=True),只是为了保持输出干净。)

注意:pd.DataFrame.sort已弃用,取而代之的是pd.DataFrame.sort_values。

添加一个你可以复制的笔记本的链接,用pandas.melt演示@DMS的答案:

df.melt(id_vars=["location", "name"], 
    var_name="date", 
    value_name="value")

https://deepnote.com/@DataScience/Unpivot-a-DataFrame-from-wide-to-long-format-lN7WlqOdSlqroI_7DGAkoA

如果你想交换你的行与列&列与行,然后尝试熊猫的转置方法:

df.T

查看参考链接: https://note.nkmk.me/en/python-pandas-t-transpose/

在MultiIndex系列中使用set_index with stack,然后在DataFrame中添加reset_index with rename:

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

我想我找到了一个更简单的解决办法

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的列名

temp1['new_column'] = temp2['name']

你现在得到了你想要的东西。