在 Pyspark 中分隔字符串和数值

Seperating string and numeric values in Pyspark

我有以下数据框。有几个 ID 具有数字或字符串值。如果 ID 是 string_value,如“B”,则 numeric_value 是字符串形式的“NULL”。对于数值,反之亦然,例如编号“D”。

    ID  string_value    numeric_value   timestamp
0   B   On              NULL            1632733508
1   B   Off             NULL            1632733508
2   A   Inactive        NULL            1632733511
3   A   Active          NULL            1632733512
4   D   NULL            450             1632733513
5   D   NULL            431             1632733515
6   C   NULL            20              1632733518
7   C   NULL            30              1632733521

现在我想通过一个包含所有唯一 ID 的现有列表为每个 ID 在一个新的数据框中分离数据框。之后,本例中的新数据框(如“B”)应删除具有“NULL”值的列。因此,如果 B 是 string_value,则应删除 numeric_value。

    ID  string_value    timestamp
0   B   On              1632733508
1   B   Off             1632733508

之后,应将具有该值的列重命名为 ID“B”,并删除 ID 列。

    B   timestamp
0   On  1632733508
1   Off 1632733508

如上所述,对于本例 ID“D”中的数值,应采用相同的程序

    ID  numeric_value   timestamp
0   D   450             1632733513
1   D   431             1632733515
    D   timestamp
0   450 1632733513
1   431 1632733515

保护值列中的原始数据类型很重要。

假设您的数据框名为 df,您的 ID 列表为 ids。您可以编写一个函数来执行您需要的操作,并为每个 id 调用它。

该函数应用所需的过滤器,并选择所需的列,并将 id 作为别名。

from pyspark.sql import functions as f

ids = ["B", "A", "D", "C"]


def split_df(df, id):
    split_df = df.filter(f.col("ID") == id).select(
        f.coalesce(f.col("string_value"), f.col("numeric_value")).alias(id),
        f.col("timestamp"),
    )
    return split_df


dfs = [split_df(df, id) for id in ids]

for df in dfs:
    df.show()

输出

+---+----------+                                                                
|  B| timestamp|
+---+----------+
| On|1632733508|
|Off|1632733508|
+---+----------+

+--------+----------+
|       A| timestamp|
+--------+----------+
|Inactive|1632733511|
|  Active|1632733512|
+--------+----------+

+---+----------+
|  D| timestamp|
+---+----------+
|450|1632733513|
|431|1632733515|
+---+----------+

+---+----------+
|  C| timestamp|
+---+----------+
| 20|1632733518|
| 30|1632733521|
+---+----------+