簡體   English   中英

使用 Pandas 將列轉換為行

[英]Convert columns into rows with Pandas

因此,我的數據集按位置包含 n 個日期的一些信息。 問題是每個日期實際上是不同的列 header。 例如 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

舊(ER)版本:<0.20

您可以使用pd.melt來獲得大部分路徑,然后排序:

>>> 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

set_indexstack一起用於MultiIndex Series ,然后為DataFrame添加reset_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

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

我想我找到了一個更簡單的解決方案

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')

將整個temp1temp2的列name連接起來

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

你現在得到了你想要的。

添加指向可以復制的筆記本的鏈接,使用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

如果您想將行與列和列與行交換,請嘗試 pandas 的轉置方法:

df.T

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

我知道這不是該主題的有效答案,但我想將列轉換為行。

我使用的是.stack() 我需要保留索引並將所有列添加為行

從此:178 行 x 73 列

對此:12994 行 x 1 列

非常有用 function :) 對不起圖片,我不知道如何發布表格哈哈

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM