提问人:Wizuriel 提问时间:2/22/2015 最后编辑:buhtzWizuriel 更新时间:11/4/2022 访问量:288207
使用 Pandas 将列转换为行
Convert columns into rows with Pandas
问:
因此,我的数据集按位置提供了一些 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
我的问题是我不知道列中有多少个日期(尽管我知道它们总是在名称之后开始)
答:
410赞
DSM
2/22/2015
#1
更新
从 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
旧版本: <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_values
。pd.DataFrame.sort
评论
0赞
3kstc
3/9/2018
@DSM这个函数的倒数是多少。即如何将 [back] 转换为df2
df
3赞
Teepeemm
3/10/2018
@3kstc 试试这里或这里。您想要研究枢轴。可能。pandas.pivot_table(df2,values='Value',index=['location','name'],columns='Date').reset_index()
1赞
Adrian
1/24/2019
@DSM有什么办法可以倒退呢?这意味着我有很多同名的行,我希望所有日期都在不同的列上
1赞
Orhan Solak
3/12/2021
@Adrian您可以在 DF 操作中解熔/反熔(又名枢轴)。有关更多详细信息,请查看此 stackoverflow.com/questions/28337117/...
8赞
Prometheus
6/25/2018
#2
我想我找到了一个更简单的解决方案
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 整体temp1
temp2
name
temp1['new_column'] = temp2['name']
你现在拥有了你所要求的东西。
10赞
jpp
11/14/2018
#3
pd.wide_to_long
您可以将前缀添加到年份列,然后直接馈送到 。我不会假装这是有效的,但在某些情况下它可能比 pd.melt
更方便,例如,当您的列已经有适当的前缀时。pd.wide_to_long
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
评论
0赞
Rabinzel
4/12/2022
我知道这已经有几年的历史了,但是在学习如何使用的差异时,我遇到了这个答案,自己测试了一下,它只是不想让我得到相同的结果(我只是得到了一个空的 df)。最后,我发现我需要添加才能得到相同的结果。当时是不同,还是从未奏效,但没有人注意到或关心?还是我错过了什么?并不是我想在这里纠正,我只是想确保我了解这些命令是怎么回事。pd.stack()
pd.melt()
pd.wide_to_long()
res
suffix=r".+"
0赞
jpp
4/13/2022
@Rabinzel,我不确定功能有什么变化。但我能说的是,我测试了代码,并且在我写这个答案时它有效。如果这是真的,那么知道为什么需要后缀参数会很有趣。
0赞
Rabinzel
4/13/2022
感谢您的回复。只是想验证问题是否在我这边,或者我误解了什么。在谷歌上搜索了一下后,我读了好几次,需要数字后缀,否则它会失败,但在文档中,它所说的只是默认设置。wide_to_long
suffix="\d+"
30赞
jezrael
2/20/2019
#4
将 set_index
与 stack
一起使用 ,然后将 add reset_index
与 :MultiIndex Series
DataFrame
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
6赞
jjurm
3/24/2021
#5
添加一个指向可以复制的笔记本的链接,使用 pandas.melt
演示@DMS的答案:
df.melt(id_vars=["location", "name"],
var_name="date",
value_name="value")
4赞
Muhammad Talha
8/10/2022
#6
如果你想用列交换你的行,用行交换列,然后尝试pandas的转置方法:
df.T
评论