pandas将一些列转换为行

Wiz*_*iel 52 python pandas

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

location    name    Jan-2010    Feb-2010    March-2010
A           "test"  12          20          30
B           "foo"   18          20          25
Run Code Online (Sandbox Code Playgroud)

我想要的是它看起来像

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
Run Code Online (Sandbox Code Playgroud)

问题是我不知道列中有多少个日期(虽然我知道它们总是会在名字后面开始)

DSM*_*DSM 136

您可以使用它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
Run Code Online (Sandbox Code Playgroud)

(可能想投入一个pd.melt,只是为了保持输出清洁.)

注意:.reset_index(drop=True) 已被弃用赞成pd.DataFrame.sort.

  • @3kstc 尝试 [此处](/sf/ask/19841/​​37117/2336725) 或 [此处](/sf/ask/3300688401/)。你想研究支点。可能是 `pandas.pivot_table(df2,values='Value',index=['location','name'],columns='Date').reset_index()`。 (2认同)

jpp*_*jpp 7

pd.wide_to_long

您可以为年份列添加前缀,然后直接提供给pd.wide_to_long. 我不会假装这是有效的,但在某些情况下它可能比 更方便pd.melt,例如当您的列已经有适当的前缀时。

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
Run Code Online (Sandbox Code Playgroud)


jez*_*ael 7

使用set_indexstackMultiIndex Series,然后DataFramereset_indexrename

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
Run Code Online (Sandbox Code Playgroud)


jju*_*urm 6

添加一个指向您可以复制的笔记本的链接,使用以下命令演示@DMS的答案pandas.melt

df.melt(id_vars=["location", "name"], 
    var_name="date", 
    value_name="value")
Run Code Online (Sandbox Code Playgroud)

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


Pro*_*eus 5

我想我找到了一个更简单的解决方案

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')
Run Code Online (Sandbox Code Playgroud)

Concat整体temp1temp2的专栏name

temp1['new_column'] = temp2['name']
Run Code Online (Sandbox Code Playgroud)

现在,您有了所需的东西。


Muh*_*lha 5

如果您想将行与列交换以及将列与行交换,请尝试pandas 的转置方法:

df.T
Run Code Online (Sandbox Code Playgroud)

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