在 pandas DataFrame 中,如何使用索引将“扁平化”变量“扁平化”成新列?
Posted
技术标签:
【中文标题】在 pandas DataFrame 中,如何使用索引将“扁平化”变量“扁平化”成新列?【英文标题】:In a pandas DataFrame, how can "flattened" variables be "unflattened" into new columns using their index? 【发布时间】:2018-05-14 18:22:58 【问题描述】:我在 pandas DataFrames 中有一些数据是使用 root_pandas 从 ROOT 文件访问的。大多数数据是可以具有各种值的简单变量。但是,有些变量是数字数组。为了加载这些数组,可以选择 flattening 变量。
因此,例如,数组变量jet_tagWeightBin
可以具有不同数量的值,具体取决于物理事件中的喷流数量。当“展平”时,可以使用索引__array_index
访问给定物理事件中每个喷流的各种值。
这是加载三个物理事件的样子。您可以看到,对于每个物理事件,都有一个 HT_jets
值,但有多个 jet_tagWeightBin
值,可以使用它们的索引访问:
| |HT_jets|jet_tagWeightBin|__array_index|
|--|-------|----------------|-------------|
|0 |319676 |1 |0 | |<---------- 1st event
|1 |319676 |5 |1 | |
|2 |319676 |1 |2 | |
|3 |319676 |5 |3 | |
|4 |200476 |5 |0 | |<------- 2nd event
|5 |200476 |2 |1 | |
|6 |200476 |1 |2 | |
|7 |200476 |1 |3 | |
|8 |520111 |5 |0 | |<---- 3rd event
|9 |520111 |1 |1 | |
|10|520111 |2 |2 | |
|11|520111 |5 |3 | |
|12|520111 |5 |4 | |
|13|520111 |2 |5 | |
代码如下:
import pandas as pd
df = pd.DataFrame(
[
[319676, 1, 0],
[319676, 5, 1],
[319676, 1, 2],
[319676, 5, 3],
[200476, 5, 0],
[200476, 2, 1],
[200476, 1, 2],
[200476, 1, 3],
[520111, 5, 0],
[520111, 1, 1],
[520111, 2, 2],
[520111, 5, 3],
[520111, 5, 4],
[520111, 2, 5],
],
columns = [
"HT_jets",
"jet_tagWeightBin",
"__array_index"
]
)
现在,我想做的是摆脱 __array_index
并添加一堆新的单值变量,如 jet_tagWeightBin_0
、jet_tagWeightBin_1
、jet_tagWeightBin_2
、...,最多根据需要。所以,我想得到这样的东西:
| |HT_jets|jet_tagWeightBin_0|jet_tagWeightBin_1|jet_tagWeightBin_2|jet_tagWeightBin_3|jet_tagWeightBin_4|jet_tagWeightBin_5|
|--|-------|------------------|------------------|------------------|------------------|------------------|------------------|
|0 |319676 |1 |5 |1 |5 |NaN |NaN |
|1 |200476 |5 |2 |1 |1 |NaN |NaN |
|2 |520111 |5 |1 |2 |5 |5 |2 |
我不确定这种类型的操作是什么,但我确信这一定是一件简单的事情。我只是不知道该怎么做。
无论如何,这是尝试的开始:
我可以添加一个具有适当名称的新列,如下所示:
df["new_name"] = df.apply(lambda row: "jet_tagWeightBin_" + str(row["__array_index"]), axis = 1)
结果如下:
| |HT_jets|jet_tagWeightBin|__array_index|new_name |
|--|-------|----------------|-------------|------------------|
|0 |319676 |1 |0 |jet_tagWeightBin_0|
|1 |319676 |5 |1 |jet_tagWeightBin_1|
|2 |319676 |1 |2 |jet_tagWeightBin_2|
|3 |319676 |5 |3 |jet_tagWeightBin_3|
|4 |200476 |5 |0 |jet_tagWeightBin_0|
|5 |200476 |2 |1 |jet_tagWeightBin_1|
|6 |200476 |1 |2 |jet_tagWeightBin_2|
|7 |200476 |1 |3 |jet_tagWeightBin_3|
|8 |520111 |5 |0 |jet_tagWeightBin_0|
|9 |520111 |1 |1 |jet_tagWeightBin_1|
|10|520111 |2 |2 |jet_tagWeightBin_2|
|11|520111 |5 |3 |jet_tagWeightBin_3|
|12|520111 |5 |4 |jet_tagWeightBin_4|
|13|520111 |2 |5 |jet_tagWeightBin_5|
这就是我所在的地方。我欢迎指导。 :)
编辑:为清楚起见,我正在处理许多变量。以下是数据中的更多列:
| |eventNumber|Mjj_MindR |HT_jets|jet_tagWeightBin|__array_index|
|--|-----------|------------|-------|----------------|-------------|
|0 |446427 |98896.421875|319676 |1 |0 | |<---------- 1st event
|1 |446427 |98896.421875|319676 |5 |1 | |
|2 |446427 |98896.421875|319676 |1 |2 | |
|3 |446427 |98896.421875|319676 |5 |3 | |
|4 |446650 |29691.271484|200476 |5 |0 | |<------- 2nd event
|5 |446650 |29691.271484|200476 |2 |1 | |
|6 |446650 |29691.271484|200476 |1 |2 | |
|7 |446650 |29691.271484|200476 |1 |3 | |
|8 |446707 |57697.246094|520111 |5 |0 | |<---- 3rd event
|9 |446707 |57697.246094|520111 |1 |1 | |
|10|446707 |57697.246094|520111 |2 |2 | |
|11|446707 |57697.246094|520111 |5 |3 | |
|12|446707 |57697.246094|520111 |5 |4 | |
|13|446707 |57697.246094|520111 |2 |5 | |
【问题讨论】:
【参考方案1】:这是一个支点问题
newDF = df.pivot(columns='array_index', values='jet_tagWeightBin', index='HT_jets')
然后只需重命名列
这给出了:
array_index 0 1 2 3 4 5
HT_jets
200476 5.0 2.0 1.0 1.0 NaN NaN
319676 1.0 5.0 1.0 5.0 NaN NaN
520111 5.0 1.0 2.0 5.0 5.0 2.0
【讨论】:
嘿,谢谢,这似乎接近我所需要的。所以,如前所述,我有一大堆变量,每个事件都有一个值,而不仅仅是HT_jets
(不能假定它本身是每个事件唯一的数字——我有变量eventNumber
,它可以用于此)。当我按照您的建议进行操作时,它会破坏我所有其他变量列。我应该如何进行?我是否应该为数组变量创建一个单独的 DataFrame,然后尝试将其与单值变量的 DataFrame 合并?
我在帖子末尾添加了几列来说明。以上是关于在 pandas DataFrame 中,如何使用索引将“扁平化”变量“扁平化”成新列?的主要内容,如果未能解决你的问题,请参考以下文章
在使用 jupyter notebook 时如何在 pandas 中使用 Dataframe 时查看完整数据? [复制]
如何在 jupyter 中像 pandas Dataframe 一样打印 Pyspark Dataframe