pandas 版本 : 我会用df.melt(...)
对于我的例子,但你需要使用pd.melt(df, ...)
反而。
文档参考:
这里的大多数解决方案将与melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html,所以要知道方法melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html, see 文档解释 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html.
将 DataFrame 从宽格式逆透视为长格式,可选择保留
标识符集。
此函数可用于将 DataFrame 转换为一种格式,其中
或多列是标识符变量(id_vars),而所有其他
列,考虑测量变量(值变量),是“未旋转的”
到行轴,只留下两个非标识符列,“变量”
和‘价值’。
参数
-
id_vars : 元组、列表或 ndarray,可选
用作标识符变量的列。
-
值变量 : 元组、列表或 ndarray,可选
要取消透视的列。如果未指定,则使用未设置为 id_vars 的所有列。
-
var_name : scalar
用于“变量”列的名称。如果没有,则使用frame.columns.name或“variable”。
-
值名称 : 标量,默认“值”
用于“值”列的名称。
-
列级 : int 或 str,可选
如果列是多重索引,则使用此级别来融化。
-
忽略索引 : 布尔值,默认 True
如果为 True,则忽略原始索引。如果为 False,则保留原始索引。索引标签会重复
有必要的。
1.1.0 版本中的新增内容。
熔化逻辑:
Melting合并多列并将数据框从宽转为长,对于问题1的解决方案(见下文),步骤是:
-
首先我们得到原始数据框。
-
然后熔体首先合并Math
and English
列并使数据框复制(更长)。
-
最后它添加了列Subject
这是该主题的Grades
列值分别为:
这就是简单的逻辑melt
函数确实如此。
解决方案:
我会解决我自己的问题。
问题一:
问题1可以用以下方法解决pd.DataFrame.melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html使用以下代码:
print(df.melt(id_vars=['Name', 'Age'], var_name='Subject', value_name='Grades'))
这段代码通过了id_vars
论证['Name', 'Age']
,然后自动将value_vars
将被设置为其他列(['Math', 'English']
),转换为该格式。
您还可以使用以下方法解决问题 1stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html像下面这样:
print(
df.set_index(["Name", "Age"])
.stack()
.reset_index(name="Grade")
.rename(columns={"level_2": "Subject"})
.sort_values("Subject")
.reset_index(drop=True)
)
这段代码设置了Name
and Age
列作为索引并堆叠其余列Math
and English
,并重置索引并分配Grade
作为列名,然后重命名另一列level_2
to 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 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html与列规格:
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 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html and groupby https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html, 使用agg
功能与', '.join
,如下所示:
print(
df.melt(id_vars=["Name", "Age"])
.groupby("value", as_index=False)
.agg(", ".join)
)
它熔化数据框,然后按等级分组并聚合它们并用逗号将它们连接起来。
stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html也可以用来解决这个问题,stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html and groupby https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html像下面这样:
print(
df.set_index(["Name", "Age"])
.stack()
.reset_index()
.rename(columns={"level_2": "Subjects", 0: "Grade"})
.groupby("Grade", as_index=False)
.agg(", ".join)
)
This stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html函数只是以相当于的方式转置数据帧melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html,然后重置索引,重命名列、组和聚合。
两种解决方案输出:
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:
我们首先融化输入数据的数据框:
df = df.melt(id_vars=['Name', 'Age'], var_name='Subject', value_name='Grades')
那么现在我们可以开始解决问题4了。
问题4可以这样解决pivot_table https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pivot_table.html,我们必须指定pivot_table https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pivot_table.html论据,values
, index
, columns
并且aggfunc
.
我们可以用下面的代码来解决:
print(
df.pivot_table("Grades", ["Name", "Age"], "Subject", aggfunc="first")
.reset_index()
.rename_axis(columns=None)
)
Output:
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 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html and groupby https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html像下面这样:
print(
df.melt(id_vars=["Name", "Age"], var_name="Subject", value_name="Grades")
.groupby("Name", as_index=False)
.agg(", ".join)
)
融化并分组Name
.
或者你可以stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html:
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 https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html并且不需要指定列,只需指定预期的列名称:
print(df.melt(var_name='Column', value_name='Value'))
这会融化整个数据框。
或者你可以stack https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.stack.html:
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
结论:
melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html是一个非常方便的功能,而且经常是必需的。一旦遇到这些类型的问题,不要忘记尝试melt https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.melt.html。它可能很好地解决你的问题。