팬더는 일부 열을 행으로 변환


115

그래서 내 데이터 세트에는 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

문제는 열에 몇 개의 날짜가 있는지 모르겠다는 것입니다 (항상 이름 뒤에 시작된다는 것을 알고 있지만)


답변:


207

업데이트
v0.20부터는 melt1 차 함수이므로 이제 사용할 수 있습니다.

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 .


@DSM은이 함수의 역수입니다. 즉, 어떻게 df2[뒤로] 변환 할 것인가df
3kstc

1
@ 3kstc 여기 또는 여기에서 시도 하십시오 . 피벗을 조사하고 싶습니다. 아마도 pandas.pivot_table(df2,values='Value',index=['location','name'],columns='Date').reset_index().
Teepeemm

1
@DSM 뒤로 갈 수있는 방법이 있습니까? 나는이 같은 이름을 가진 행을 많이 가지고 있음을 의미 나는 모든 날짜가 다른 컬럼에되고 싶은 것
아드리안

17

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

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

전체 CONCAT temp1temp2의 열name

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

이제 당신은 당신이 요청한 것을 얻었습니다.


4

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.