gấu trúc chuyển đổi một số cột thành hàng


115

Vì vậy, tập dữ liệu của tôi có một số thông tin theo vị trí cho n ngày. Vấn đề là mỗi ngày thực sự là một tiêu đề cột khác nhau. Ví dụ: CSV trông giống như

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

Điều tôi muốn là nó trông như thế nào

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

vấn đề là tôi không biết có bao nhiêu ngày trong cột (mặc dù tôi biết chúng sẽ luôn bắt đầu sau tên)


Câu trả lời:


207

CẬP NHẬT
Từ v0.20, meltlà hàm đặt hàng đầu tiên, bây giờ bạn có thể sử dụng

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

PHIÊN BẢN CŨ (ER): <0,20

Bạn có thể sử dụng pd.melthầu hết các con đường đến đó, sau đó sắp xếp:

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

(Có thể muốn ném vào một .reset_index(drop=True), chỉ để giữ cho đầu ra sạch sẽ.)

Lưu ý : pd.DataFrame.sort đã không còn được ủng hộ pd.DataFrame.sort_values.


@DSM sẽ là nghịch đảo của hàm này. tức là sẽ như thế nào một chuyển đổi df2[lại] đểdf
3kstc

1
@ 3kstc Hãy thử tại đây hoặc tại đây . Bạn đang muốn xem xét các trục. Có thể pandas.pivot_table(df2,values='Value',index=['location','name'],columns='Date').reset_index().
Teepeemm

1
@DSM có cách nào để quay ngược lại không? Có nghĩa là tôi có rất nhiều hàng có tên giống nhau và tôi muốn tất cả các ngày nằm trên các cột khác nhau
Adrian

17

Sử dụng set_indexvới stackcho MultiIndex Series, sau đó cho DataFramethêm reset_indexvới 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

5

Tôi đoán tôi đã tìm thấy một giải pháp đơn giản hơn

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

Kết hợp toàn bộ temp1với temp2cột củaname

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

Bây giờ bạn có những gì bạn yêu cầu.


4

pd.wide_to_long

Bạn có thể thêm tiền tố vào các cột năm của mình và sau đó cấp dữ liệu trực tiếp cho pd.wide_to_long. Tôi sẽ không giả vờ rằng điều này là hiệu quả , nhưng nó có thể trong một số trường hợp thuận tiện hơn pd.melt, ví dụ: khi các cột của bạn đã có tiền tố thích hợp.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.