问题内容
在 pandas 标签上,我经常看到用户询问有关在 pandas 中融化数据帧的问题。我将尝试针对这个主题进行规范的问答(自我回答)。
我要澄清:
什么是熔化?
如何使用melt?
什么时候使用melt?
我看到一些有关融化的热门问题,例如:
-
使用 pandas 将列转换为行:这个实际上可能很好,但更多的解释会更好。
-
pandas melt function:一个很好的问题,答案也很好,但是有点太模糊了,没有太多解释。
-
融化 pandas 数据框:也是一个很好的答案!但这只是针对特定情况,这很简单,只有
pd.melt(df)
-
pandas 数据框使用列作为行(融化):非常整洁!但问题是,它仅针对op提出的具体问题,也需要使用
pivot_table
。
所以我将尝试针对这个主题进行规范的问答。
数据集:
我将在这个随机年龄的随机人的随机成绩数据集中找到所有答案(更容易解释答案:d):
import pandas as pd
df = pd.dataframe({'name': ['bob', 'john', 'foo', 'bar', 'alex', 'tom'],
'math': ['a+', 'b', 'a', 'f', 'd', 'c'],
'english': ['c', 'b', 'b', 'a+', 'f', 'a'],
'age': [13, 16, 16, 15, 15, 13]})
登录后复制
>>> df
name math english age
0 bob a+ c 13
1 john b b 16
2 foo a b 16
3 bar f a+ 15
4 alex d f 15
5 tom c a 13
登录后复制
问题:
问题 1:
如何融化数据框以使原始数据框变为以下内容?
name age subject grade
0 bob 13 english c
1 john 16 english b
2 foo 16 english b
3 bar 15 english a+
4 alex 17 english f
5 tom 12 english a
6 bob 13 math a+
7 john 16 math b
8 foo 16 math a
9 bar 15 math f
10 alex 17 math d
11 tom 12 math c
登录后复制登录后复制
我想对其进行转置,以便一列是每个科目,其他列是学生的重复姓名及其年龄和分数。
问题 2:
这和问题1类似,但是这次我想让问题1输出subject
列只有math
,我想过滤掉english
列:
name age subject grades
0 bob 13 math a+
1 john 16 math b
2 foo 16 math a
3 bar 15 math f
4 alex 15 math d
5 tom 13 math c
登录后复制
我希望输出如上所示。
问题 3:
如果我要对熔化进行分组并按学生的分数排序,我该如何做到这一点,以获得如下所示的所需输出:
value name subjects
0 a foo, tom math, english
1 a+ bob, bar math, english
2 b john, john, foo math, english, english
3 c tom, bob math, english
4 d alex math
5 f bar, alex math, english
登录后复制
我需要对其进行排序,名称用逗号分隔,并且 subjects
分别以相同的顺序用逗号分隔。
问题 4:
我如何解冻一个熔化的数据框?假设我已经融化了这个数据框:
df = df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades')
登录后复制
成为:
name age subject grades
0 bob 13 math a+
1 john 16 math b
2 foo 16 math a
3 bar 15 math f
4 alex 15 math d
5 tom 13 math c
6 bob 13 english c
7 john 16 english b
8 foo 16 english b
9 bar 15 english a+
10 alex 15 english f
11 tom 13 english a
登录后复制
那么我如何将其转换回原始数据框,如下所示?
name math english age
0 bob a+ c 13
1 john b b 16
2 foo a b 16
3 bar f a+ 15
4 alex d f 15
5 tom c a 13
登录后复制
问题 5:
如果我要按学生姓名分组并用逗号分隔科目和成绩,我会怎么做?
name subject grades
0 alex math, english d, f
1 bar math, english f, a+
2 bob math, english a+, c
3 foo math, english a, b
4 john math, english b, b
5 tom math, english c, a
登录后复制
我想要一个像上面这样的数据框。
问题 6:
如果我要完全融化我的数据框,所有列都作为值,我会怎么做?
Column Value
0 Name Bob
1 Name John
2 Name Foo
3 Name Bar
4 Name Alex
5 Name Tom
6 Math A+
7 Math B
8 Math A
9 Math F
10 Math D
11 Math C
12 English C
13 English B
14 English B
15 English A+
16 English F
17 English A
18 Age 13
19 Age 16
20 Age 16
21 Age 15
22 Age 15
23 Age 13
登录后复制
我想要一个像上面这样的数据框。所有列作为值。
正确答案
pandas 版本 :我将使用 df.melt(...)
作为我的示例,但您需要使用 pd.melt(df, .. .)
代替。
文档参考:
这里的大多数解决方案都将与 melt
,所以要知道方法melt
,请参阅文档说明。
熔化逻辑:
melting合并多列,将dataframe由宽转长,解决问题1(见下文),步骤为:
首先我们得到了原始数据帧。
然后,melt 首先合并 math
和 english
列,并使数据帧复制(更长)。
最后它添加了 subject
列,它分别是 grades
列值的主题:
这是 melt
函数的简单逻辑。
解决方案:
问题 1:
问题 1 可以使用 pd.dataframe.melt
解决 使用以下代码:
print(df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades'))
登录后复制
此代码将 id_vars
参数传递给 ['name', 'age']
,然后自动将 value_vars
设置为其他列(['math', 'english']
),这是转置的转换为该格式。
您还可以使用 stack
解决问题 1 > 像下面这样:
print(
df.set_index(["name", "age"])
.stack()
.reset_index(name="grade")
.rename(columns={"level_2": "subject"})
.sort_values("subject")
.reset_index(drop=true)
)
登录后复制
此代码将 name
和 age
列设置为索引,并堆叠其余列 math
和 english
,并重置索引并指定 grade
作为列名称,然后将其他列重命名为 level_2phpcnendcphp cn 到
subject
然后按subject
列,最后再次重置索引。
这两个解决方案输出:
name age subject grade
0 bob 13 english c
1 john 16 english b
2 foo 16 english b
3 bar 15 english a+
4 alex 17 english f
5 tom 12 english a
6 bob 13 math a+
7 john 16 math b
8 foo 16 math a
9 bar 15 math f
10 alex 17 math d
11 tom 12 math c
登录后复制登录后复制
问题 2:
这和我的第一个问题类似,但是这个我只在 math
列中进行过滤,这时候 value_vars
参数就可以派上用场了,如下所示:
print(
df.melt(
id_vars=["name", "age"],
value_vars="math",
var_name="subject",
value_name="grades",
)
)
登录后复制
或者我们也可以使用 stack
与列规格:
print(
df.set_index(["name", "age"])[["math"]]
.stack()
.reset_index(name="grade")
.rename(columns={"level_2": "subject"})
.sort_values("subject")
.reset_index(drop=true)
)
登录后复制
这两种解决方案都给出:
name age subject grade
0 bob 13 math a+
1 john 16 math b
2 foo 16 math a
3 bar 15 math f
4 alex 15 math d
5 tom 13 math c
登录后复制
问题 3:
问题3可以通过melt
解决和 groupby
,使用 agg
函数和 ' , '.join
,如下所示:
print(
df.melt(id_vars=["name", "age"])
.groupby("value", as_index=false)
.agg(", ".join)
)
登录后复制
它会融合数据框,然后按等级进行分组,聚合它们并用逗号将它们连接起来。
stack
也可以用来解决这个问题,与 stack
和 groupby
如下所示:
print(
df.set_index(["name", "age"])
.stack()
.reset_index()
.rename(columns={"level_2": "subjects", 0: "grade"})
.groupby("grade", as_index=false)
.agg(", ".join)
)
登录后复制
这个 stack
函数只是转置数据帧以相当于 melt
的方式,然后重置索引,重命名列、组和聚合。
两种解决方案输出:
grade name subjects
0 a foo, tom math, english
1 a+ bob, bar math, english
2 b john, john, foo math, english, english
3 c bob, tom english, math
4 d alex math
5 f bar, alex math, english
登录后复制
问题 4:
这可以通过 pivot_table
来解决。我们必须指定参数 values
、index
、columns
以及 aggfunc
。
我们可以用下面的代码来解决这个问题:
print(
df.pivot_table("grades", ["name", "age"], "subject", aggfunc="first")
.reset_index()
.rename_axis(columns=none)
)
登录后复制
输出:
name age english math
0 alex 15 f d
1 bar 15 a+ f
2 bob 13 c a+
3 foo 16 b a
4 john 16 b b
5 tom 13 a c
登录后复制
融化的数据帧被转换回与原始数据帧完全相同的格式。
我们首先旋转融化的数据框,然后重置索引并删除列轴名称。
问题 5:
问题5可以通过melt
解决和 groupby
如下所示:
print(
df.melt(id_vars=["name", "age"], var_name="subject", value_name="grades")
.groupby("name", as_index=false)
.agg(", ".join)
)
登录后复制
融化并按 name
分组。
或者您可以stack
: p>
print(
df.set_index(["name", "age"])
.stack()
.reset_index()
.groupby("name", as_index=false)
.agg(", ".join)
.rename({"level_2": "subjects", 0: "grades"}, axis=1)
)
登录后复制
两个代码输出:
name subjects grades
0 alex math, english d, f
1 bar math, english f, a+
2 bob math, english a+, c
3 foo math, english a, b
4 john math, english b, b
5 tom math, english c, a
登录后复制
问题 6:
问题6可以通过melt
解决并且不需要指定列,只需指定预期的列名称:
print(df.melt(var_name='column', value_name='value'))
登录后复制
这会融化整个数据框。
或者您可以stack
: p>
print(
df.stack()
.reset_index(level=1)
.sort_values("level_1")
.reset_index(drop=true)
.set_axis(["column", "value"], axis=1)
)
登录后复制
两个代码输出:
Column Value
0 Age 16
1 Age 15
2 Age 15
3 Age 16
4 Age 13
5 Age 13
6 English A+
7 English B
8 English B
9 English A
10 English F
11 English C
12 Math C
13 Math A+
14 Math D
15 Math B
16 Math F
17 Math A
18 Name Alex
19 Name Bar
20 Name Tom
21 Name Foo
22 Name John
23 Name Bob
登录后复制
以上就是如何融化 pandas 数据框?的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!