Heim  >  Artikel  >  Backend-Entwicklung  >  Wie schmelze ich den Pandas-Datenrahmen?

Wie schmelze ich den Pandas-Datenrahmen?

WBOY
WBOYnach vorne
2024-02-09 23:30:14392Durchsuche

如何融化 pandas 数据框?

Frageninhalt

Auf dem Pandas-Tag sehe ich oft, dass Benutzer Fragen zum Schmelzen von Datenrahmen in Pandas stellen. Ich werde versuchen, eine kanonische Frage-und-Antwort-Runde (Selbstantwort) zu diesem Thema zu verfassen.

Ich möchte klarstellen:

  1. Was ist Schmelzen?

  2. Wie verwende ich Schmelze?

  3. Wann sollte Schmelze verwendet werden?

Ich habe einige beliebte Fragen zum Schmelzen gesehen, wie zum Beispiel:

  • Spalten mit Pandas in Zeilen umwandeln: Das könnte tatsächlich gut sein, aber mehr Erklärung wäre schön.

  • Pandas-Melt-Funktion: Eine gute Frage mit einer guten Antwort, aber etwas zu vage ohne viel Erklärung.

  • Melting Pandas Dataframe: Auch eine tolle Antwort! Aber das ist nur für einen konkreten Fall, es ist einfach, einfach pd.melt(df)

  • Pandas-Datenrahmen mit Spalten als Zeilen (geschmolzen) : Sehr ordentlich! Das Problem ist jedoch, dass es nur auf die spezifische Frage des OP eingeht, die ebenfalls die Verwendung von pivot_table erfordert.

Also werde ich versuchen, eine kanonische Frage-und-Antwort-Runde zu diesem Thema durchzuführen.

Datensatz:

Ich werde alle Antworten in diesem Datensatz mit zufälligen Noten für zufällige Personen in zufälligem Alter finden (die Antwort lässt sich einfacher erklären :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

Frage:

Frage 1:

Wie schmelze ich einen Datenrahmen, sodass der ursprüngliche Datenrahmen wie folgt aussieht?

    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

Ich möchte es so umsetzen, dass eine Spalte für jedes Fach ist und die anderen Spalten die wiederholten Namen der Schüler zusammen mit ihrem Alter und ihren Noten enthalten.

Frage 2:

Dies ähnelt Frage 1, aber dieses Mal möchte ich, dass Frage 1 subject列只有math,我想过滤掉englishSpalte:

ausgibt
   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

Ich möchte, dass die Ausgabe wie oben aussieht.

Frage 3:

Wenn ich die Schmelzen gruppieren und nach den Ergebnissen der Schüler sortieren würde, wie würde ich das tun, um das gewünschte Ergebnis wie folgt zu erhalten:

  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

Ich muss die durch Kommas getrennten Namen und die durch Kommas getrennten subjects in derselben Reihenfolge sortieren.

Frage 4:

Wie kann ich einen geschmolzenen Datenrahmen auftauen ? Nehmen wir an, ich habe diesen Datenrahmen geschmolzen:

df = df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades')

Werde:

    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

Wie konvertiere ich es also wie unten wieder in den ursprünglichen Datenrahmen?

   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

Frage 5:

Was würde ich tun, wenn ich Schüler nach Namen gruppieren und Fächer und Noten durch Kommas trennen möchte?

   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

Ich möchte einen Datenrahmen wie oben.

Frage 6:

Was würde ich tun, wenn ich meinen Datenrahmen mit allen Spalten als Werten vollständig verschmelzen würde?

     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

Ich möchte einen Datenrahmen wie oben. Alle Spalten als Werte.


Richtige Antwort


Hinweis für Pandas-Version < 0.20.0 : Ich werde stattdessen df.melt(...) 作为我的示例,但您需要使用 pd.melt(df, .. .) verwenden.

Dokumentreferenz:

Die meisten der hier aufgeführten Lösungen funktionieren mit melt,所以要知道方法melt. Um zu erfahren, wie , lesen Sie bitte die

Dokumentationsanweisungen

.

Schmelzende Logik:

    Melting führt mehrere Spalten zusammen, konvertiert den Datenrahmen von breit nach lang und löst Problem 1 (siehe unten). Die Schritte sind:
  1. Zuerst erhalten wir den Originaldatenrahmen.
  2. mathenglish

    Dann führt Melt zuerst die
  3. Spalten zusammen und macht den Datenrahmen dupliziert (länger).
  4. subject 列,它分别是 grades

    Schließlich werden
  5. Themen für Spaltenwerte hinzugefügt:

melt

Das ist die einfache Logik der

-Funktion.

Lösung:

Frage 1: pd.dataframe.meltProblem 1 kann mit

mithilfe des folgenden Codes gelöst werden: id_vars 参数传递给 ['name', 'age'],然后自动将 value_vars 设置为其他列(['math', 'english']

print(df.melt(id_vars=['name', 'age'], var_name='subject', value_name='grades'))

Dieser Code konvertiert

), also die Transponierte, in dieses Format. stackSie können 解决问题 1 >

auch wie folgt verwenden: nameage 列设置为索引,并堆叠其余列 mathenglish,并重置索引并指定 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)
)

Dieser Code legt die Spalten name und age als Index fest und stapelt die verbleibenden Spalten

und setzt den Index zurück und gibt grade als Spaltennamen an, Benennen Sie dann die anderen Spalten in level_2phpcnendcphp cn in <code>subject um, drücken Sie dann auf die Spalte subject und setzen Sie schließlich den Index erneut zurück.

🎜Die beiden Lösungen geben Folgendes aus: 🎜
    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也可以用来解决这个问题,与 stackgroupby 如下所示:

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 来解决。我们必须指定参数 valuesindexcolumns 以及 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

Das obige ist der detaillierte Inhalt vonWie schmelze ich den Pandas-Datenrahmen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen