如何在 python pandas 中重新构造它?合并,取消堆叠还是什么?
How to re-structure this in python pandas? Merge, unstack or what?
正在尝试重新构建格式如下的数据框:
key ref name value
0 k1 None N1 A
1 None k1 N2 B
2 None k1 N3 C
3 k2 None N4 D
4 k3 None N5 E
5 None k3 N6 F
6 None k3 N7 G
# In code
df = pd.DataFrame(columns=['key', 'ref', 'name', 'value'],
data=[
['k1',None,'N1','A'],
[None,'k1','N2','B'],
[None,'k1','N3','C'],
['k2',None,'N4','D'],
['k3',None,'N5','E'],
[None,'k3','N6','F'],
[None,'k3','N7','G']])
进入这个:
key ref name value name2 value2 name3 value3
0 k1 k1 N1 A N2 B N3 C
1 k2 None N4 D None None None None
2 k3 k3 N5 E N6 F N7 G
但正在努力做到正确。 'key' 和 'ref' 不是上面的索引,但请随意详细说明如何以这种方式使用它们(源是这种格式的 Excel 文件),如果这是一部分的话的解决方案。目标是将名称和值相应地映射到示例...(然后将丢弃键和引用)
尝试过合并和堆栈,但无法正常工作...
注意以下规则:
- 'key' 列中的键是唯一的(除非 emtpy/None)
- 'ref' 列中的引用最多有 2 个相同的值
换句话说:
- 任何'key'都有0-2个对应'ref'
- 任何 'ref' 匹配一个,并且只有一个,对应 'key'
也许这就是您所需要的:
import pandas as pd
df = pd.DataFrame(
columns=["key", "ref", "name", "value"],
data=[
["k1", None, "N1", "A"],
[None, "k1", "N2", "B"],
[None, "k1", "N3", "C"],
["k2", None, "N4", "D"],
["k3", None, "N5", "E"],
[None, "k3", "N6", "F"],
[None, "k3", "N7", "G"],
],
)
print(df)
ind = df["key"].isna()
df1 = df.loc[~ind]
df2 = df.loc[ind]
combo = (
df1.merge(df2[["ref", "name", "value"]], left_on="key", right_on="ref", how="left")
.fillna("")
.groupby("key")
.agg(name=pd.NamedAgg("name_y", ":".join), value=pd.NamedAgg("value_y", ":".join))
)
for c in ["name", "value"]:
dx = combo[c].str.split(":", expand=True).add_prefix(c)
df1 = df1.merge(dx, left_on="key", right_index=True)
print(df1)
首先,我们将 df 拆分为两个单独的数据帧,具体取决于列 key
中是否有条目。
其次,我们创建一个组合数据框,将 df1
与聚合的 df2
合并,其中聚合为 value
和 name
创建两列,其中所有条目都连接成以“:”分隔的字符串。
最后,我们使用 str.split
和 expand=True
将这些字符串拆分为单独的列并将其与 df1 合并。
key ref name value name0 name1 value0 value1
0 k1 None N1 A N2 N3 B C
3 k2 None N4 D None None
4 k3 None N5 E N6 N7 F G
None
条目还不太正确,但很容易修复。
正在尝试重新构建格式如下的数据框:
key ref name value
0 k1 None N1 A
1 None k1 N2 B
2 None k1 N3 C
3 k2 None N4 D
4 k3 None N5 E
5 None k3 N6 F
6 None k3 N7 G
# In code
df = pd.DataFrame(columns=['key', 'ref', 'name', 'value'],
data=[
['k1',None,'N1','A'],
[None,'k1','N2','B'],
[None,'k1','N3','C'],
['k2',None,'N4','D'],
['k3',None,'N5','E'],
[None,'k3','N6','F'],
[None,'k3','N7','G']])
进入这个:
key ref name value name2 value2 name3 value3
0 k1 k1 N1 A N2 B N3 C
1 k2 None N4 D None None None None
2 k3 k3 N5 E N6 F N7 G
但正在努力做到正确。 'key' 和 'ref' 不是上面的索引,但请随意详细说明如何以这种方式使用它们(源是这种格式的 Excel 文件),如果这是一部分的话的解决方案。目标是将名称和值相应地映射到示例...(然后将丢弃键和引用)
尝试过合并和堆栈,但无法正常工作...
注意以下规则:
- 'key' 列中的键是唯一的(除非 emtpy/None)
- 'ref' 列中的引用最多有 2 个相同的值
换句话说:
- 任何'key'都有0-2个对应'ref'
- 任何 'ref' 匹配一个,并且只有一个,对应 'key'
也许这就是您所需要的:
import pandas as pd
df = pd.DataFrame(
columns=["key", "ref", "name", "value"],
data=[
["k1", None, "N1", "A"],
[None, "k1", "N2", "B"],
[None, "k1", "N3", "C"],
["k2", None, "N4", "D"],
["k3", None, "N5", "E"],
[None, "k3", "N6", "F"],
[None, "k3", "N7", "G"],
],
)
print(df)
ind = df["key"].isna()
df1 = df.loc[~ind]
df2 = df.loc[ind]
combo = (
df1.merge(df2[["ref", "name", "value"]], left_on="key", right_on="ref", how="left")
.fillna("")
.groupby("key")
.agg(name=pd.NamedAgg("name_y", ":".join), value=pd.NamedAgg("value_y", ":".join))
)
for c in ["name", "value"]:
dx = combo[c].str.split(":", expand=True).add_prefix(c)
df1 = df1.merge(dx, left_on="key", right_index=True)
print(df1)
首先,我们将 df 拆分为两个单独的数据帧,具体取决于列 key
中是否有条目。
其次,我们创建一个组合数据框,将 df1
与聚合的 df2
合并,其中聚合为 value
和 name
创建两列,其中所有条目都连接成以“:”分隔的字符串。
最后,我们使用 str.split
和 expand=True
将这些字符串拆分为单独的列并将其与 df1 合并。
key ref name value name0 name1 value0 value1
0 k1 None N1 A N2 N3 B C
3 k2 None N4 D None None
4 k3 None N5 E N6 N7 F G
None
条目还不太正确,但很容易修复。