Pada tag panda, saya sering melihat pengguna bertanya soalan tentang mencairkan bingkai data dalam panda. Saya akan cuba melakukan Soal Jawab (jawapan sendiri) kanonik mengenai topik ini.
Saya ingin menjelaskan:
Apa itu mencair?
Bagaimana cara menggunakan melt?
Bila nak guna melt?
Saya melihat beberapa soalan popular tentang lebur, seperti:
Tukar lajur kepada baris menggunakan panda: Yang ini sebenarnya mungkin bagus, tetapi lebih baik penjelasannya.
fungsi panda cair: Soalan yang bagus dengan jawapan yang baik, tetapi agak terlalu kabur tanpa banyak penjelasan.
Bingkai data panda cair: Juga jawapan yang bagus! Tetapi itu hanya untuk kes tertentu, ia mudah, hanya pd.melt(df)
bingkai data panda menggunakan lajur sebagai baris (cair) : Sangat kemas! Tetapi masalahnya, ia hanya menangani soalan khusus yang ditanya oleh OP, yang juga memerlukan penggunaan pivot_table
.
Jadi saya akan cuba buat Soal Jawab berkanun mengenai topik ini.
Saya akan menemui semua jawapan dalam set data gred rawak ini untuk orang rawak pada usia rawak (lebih mudah untuk menerangkan jawapannya :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
Bagaimana untuk mencairkan kerangka data supaya kerangka data asal menjadi seperti berikut?
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
Saya ingin mengubahnya supaya satu lajur untuk setiap mata pelajaran dan lajur yang lain adalah nama berulang pelajar berserta umur dan markah mereka.
Ini serupa dengan soalan 1, tetapi kali ini saya mahu soalan 1 dikeluarkan subject
列只有math
,我想过滤掉english
lajur:
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
Saya mahu output kelihatan seperti di atas.
Sekiranya saya mengumpulkan leburan dan menyusunnya mengikut markah pelajar, bagaimana saya akan melakukannya untuk mendapatkan output yang diingini seperti ini:
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
Saya perlu mengisihnya dengan nama yang dipisahkan dengan koma dan subjects
dipisahkan dengan koma dalam susunan yang sama.
Bagaimana cara saya menyah beku bingkai data cair? Katakan saya telah mencairkan kerangka data ini:
df = df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades')
Menjadi:
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
Jadi bagaimana cara saya menukarnya kembali kepada bingkai data asal seperti yang ditunjukkan di bawah?
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
Apakah yang akan saya lakukan jika saya ingin mengumpulkan pelajar mengikut nama dan mengasingkan mata pelajaran dan gred dengan koma?
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
Saya mahukan dataframe seperti di atas.
Jika saya mencairkan sepenuhnya bingkai data saya dengan semua lajur sebagai nilai, apakah yang akan saya lakukan?
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
Saya mahukan dataframe seperti di atas. Semua lajur sebagai nilai.
Nota untuk versi panda < 0.20.0 : Saya akan menggunakan df.melt(...)
作为我的示例,但您需要使用 pd.melt(df, .. .)
sebaliknya.
Kebanyakan penyelesaian di sini akan berfungsi dengan melt
< 一起使用/a>,所以要知道方法melt
, jadi untuk mengetahui caranya sila lihat
Logik Lebur:
math
和 english
subject
列,它分别是 grades
melt
Soalan 1:
pd.dataframe.melt
Masalah 1 boleh diselesaikan menggunakan
menggunakan kod berikut: id_vars
参数传递给 ['name', 'age']
,然后自动将 value_vars
设置为其他列(['math', 'english']
print(df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades'))
), iaitu transpose, ke dalam format ini.
stack
Anda juga boleh menggunakan
seperti di bawah: name
和 age
列设置为索引,并堆叠其余列 math
和 english
,并重置索引并指定 grade
作为列名称,然后将其他列重命名为 level_2phpcnendcphp cn 到 <code>subject
然后按subject
print( df.set_index(["name", "age"]) .stack() .reset_index(name="grade") .rename(columns={"level_2": "subject"}) .sort_values("subject") .reset_index(drop=true) )
age
sebagai indeks dan menyusun lajur yang tinggal dan menetapkan semula indeks dan menentukan gred
sebagai nama lajur, Kemudian namakan semula lajur lain kepada level_2phpcnendcphp cn kepada <code>subject
kemudian tekan lajur subject
dan akhirnya set semula indeks sekali lagi.
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
这和我的第一个问题类似,但是这个我只在 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可以通过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
这可以通过 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
融化的数据帧被转换回与原始数据帧完全相同的格式。
我们首先旋转融化的数据框,然后重置索引并删除列轴名称。
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可以通过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
Atas ialah kandungan terperinci Bagaimana untuk mencairkan bingkai data panda?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!