在 pandas 中使用列名作为新属性
Using column name as a new attribute in pandas
我有如下数据结构
Date Agric Food
01/01/1990 1.3 0.9
01/02/1990 1.2 0.9
我想把它转换成格式
Date Sector Beta
01/01/1990 Agric 1.3
01/02/1990 Agric 1.2
01/01/1990 Food 0.9
01/02/1990 Food 0.9
虽然我确定我可以通过复杂的方式做到这一点,但有没有办法只用几行代码就可以做到这一点?
使用set_index
和stack
:
df.set_index('Date').rename_axis('Sector',axis=1).stack()\
.reset_index(name='Beta')
输出:
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/01/1990 Food 0.9
2 01/02/1990 Agric 1.2
3 01/02/1990 Food 0.9
df.melt('Date', var_name='Sector', value_name='Beta')
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/02/1990 Agric 1.2
2 01/01/1990 Food 0.9
3 01/02/1990 Food 0.9
或者您可以使用 lreshape
df=pd.lreshape(df2, {'Date': ["Date","Date"], 'Beta': ['Agric', 'Food']})
df['Sector']=sorted(df2.columns.tolist()[1:3]*2)
Out[654]:
Date Beta Sector
0 01/01/1990 1.3 Agric
1 01/02/1990 1.2 Agric
2 01/01/1990 0.9 Food
3 01/02/1990 0.9 Food
如果你有 48 列
df=pd.lreshape(df2, {'Date':['Date']*2, 'Beta': df2.columns.tolist()[1:3]})
df['Sector']=sorted(df2.columns.tolist()[1:3]*2)
同样对于列 Sector ,通过
创建它更安全
import itertools
list(itertools.chain.from_iterable(itertools.repeat(x, 2) for x in df2.columns.tolist()[1:3]))
编辑原因 lreshap
未记录(根据@ Ted Petrou 如果可能最好使用可用的 DataFrame 方法,然后如果 none 可用则使用已记录功能。pandas 一直在寻求改进其 API 并且调用未记录的、旧的和实验性的函数,如 lreshape 任何东西都是没有根据的。此外,这个问题是 melt 或 stack 的一个非常简单的用例。它是一个为 pandas 的新手设置不好的先例来 Stack Overflow 并使用 lreshape 找到赞成的答案。 )
此外,如果您想了解更多信息,可以在 github
查看
下面是使用pd.wide_to_long
的方法
dict1 = {'Agric':'A_Agric','Food':'A_Food'}
df2 = df.rename(columns=dict1)
pd.wide_to_long(df2.reset_index(),['A'],i='Date',j='Sector',sep='_',suffix='.').reset_index().drop('index',axis=1).rename(columns={'A':'Beta '})
Out[2149]:
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/02/1990 Agric 1.2
2 01/01/1990 Food 0.9
3 01/02/1990 Food 0.9
我有如下数据结构
Date Agric Food
01/01/1990 1.3 0.9
01/02/1990 1.2 0.9
我想把它转换成格式
Date Sector Beta
01/01/1990 Agric 1.3
01/02/1990 Agric 1.2
01/01/1990 Food 0.9
01/02/1990 Food 0.9
虽然我确定我可以通过复杂的方式做到这一点,但有没有办法只用几行代码就可以做到这一点?
使用set_index
和stack
:
df.set_index('Date').rename_axis('Sector',axis=1).stack()\
.reset_index(name='Beta')
输出:
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/01/1990 Food 0.9
2 01/02/1990 Agric 1.2
3 01/02/1990 Food 0.9
df.melt('Date', var_name='Sector', value_name='Beta')
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/02/1990 Agric 1.2
2 01/01/1990 Food 0.9
3 01/02/1990 Food 0.9
或者您可以使用 lreshape
df=pd.lreshape(df2, {'Date': ["Date","Date"], 'Beta': ['Agric', 'Food']})
df['Sector']=sorted(df2.columns.tolist()[1:3]*2)
Out[654]:
Date Beta Sector
0 01/01/1990 1.3 Agric
1 01/02/1990 1.2 Agric
2 01/01/1990 0.9 Food
3 01/02/1990 0.9 Food
如果你有 48 列
df=pd.lreshape(df2, {'Date':['Date']*2, 'Beta': df2.columns.tolist()[1:3]})
df['Sector']=sorted(df2.columns.tolist()[1:3]*2)
同样对于列 Sector ,通过
创建它更安全import itertools
list(itertools.chain.from_iterable(itertools.repeat(x, 2) for x in df2.columns.tolist()[1:3]))
编辑原因 lreshap
未记录(根据@ Ted Petrou 如果可能最好使用可用的 DataFrame 方法,然后如果 none 可用则使用已记录功能。pandas 一直在寻求改进其 API 并且调用未记录的、旧的和实验性的函数,如 lreshape 任何东西都是没有根据的。此外,这个问题是 melt 或 stack 的一个非常简单的用例。它是一个为 pandas 的新手设置不好的先例来 Stack Overflow 并使用 lreshape 找到赞成的答案。 )
此外,如果您想了解更多信息,可以在 github
查看下面是使用pd.wide_to_long
dict1 = {'Agric':'A_Agric','Food':'A_Food'}
df2 = df.rename(columns=dict1)
pd.wide_to_long(df2.reset_index(),['A'],i='Date',j='Sector',sep='_',suffix='.').reset_index().drop('index',axis=1).rename(columns={'A':'Beta '})
Out[2149]:
Date Sector Beta
0 01/01/1990 Agric 1.3
1 01/02/1990 Agric 1.2
2 01/01/1990 Food 0.9
3 01/02/1990 Food 0.9