Python 从目录列表中添加新列
我有一个Python 从目录列表中添加新列,python,pandas,Python,Pandas,我有一个DataFrame,其中有一列由dict组成,我想提取所有键和值,并将它们作为两个新列 a b 0 1 {'a': 1, 'b': 2} 1 2 {'k': 4, 'v': 6} 2 3 {'z': 3} 输出将是 a k v 0 1 a 1 1 1 b 2 2 2 k 4 3 2 v 6 4 3 z 3 对元组列表使用列表理解和展平值,并传递给DataFrame构造函数: L
DataFrame
,其中有一列由dict
组成,我想提取所有键和值,并将它们作为两个新列
a b
0 1 {'a': 1, 'b': 2}
1 2 {'k': 4, 'v': 6}
2 3 {'z': 3}
输出将是
a k v
0 1 a 1
1 1 b 2
2 2 k 4
3 2 v 6
4 3 z 3
对元组列表使用列表理解和展平值,并传递给
DataFrame
构造函数:
L = [(x, k, v) for x, y in df[['a','b']].values for k, v in y.items()]
df = pd.DataFrame(L, columns=['a','k','v'])
print (df)
a k v
0 1 a 1
1 1 b 2
2 2 k 4
3 2 v 6
4 3 z 3
编辑:对于使用唯一索引的通用解决方案,可以使用解决方案修改来提取b
列,按索引值添加新列idx
,转换为索引并最后使用:
首先,我创建了原始数据帧:
df = pd.DataFrame({'a': [1, 2, 3],
'b': [{'a': 1, 'b': 2},
{'k': 4, 'v': 6},
{'z': 3}]
})
然后,迭代数据帧的行,并迭代B列中的字典:
ts = list()
for row in df.itertuples():
for key, value in row.b.items():
t = (row.Index, row.a, key, value)
ts.append(t)
print(pd.DataFrame(data=ts, columns=['Index', 'a', 'k', 'v']).set_index('Index'))
a k v
Index
0 1 a 1
0 1 b 2
1 2 k 4
1 2 v 6
2 3 z 3
您可以尝试,并且:
您可以展开字典,
explode
列并应用pd.Series
函数以获得结果:
df = pd.DataFrame({"a": [1, 2, 3], "b": [{"a": 1, "b": 2}, {"k": 4, "v": 6}, {"z": 3}]})
divider = df.columns.get_loc("b")
# expand dictionary within the `b` column
df["b"] = [tuple(entry.items()) for entry in df.b]
# merge dataframe before `b`, the exploded `b` column, and the dataframe after `b`
merger = (
df.iloc[:, :-divider],
df.b.explode().apply(pd.Series).set_axis(["k", "v"], axis=1),
df.iloc[:, : -(divider + 1)],
)
pd.concat(merger, axis=1)
a k v
0 1 a 1
0 1 b 2
1 2 k 4
1 2 v 6
2 3 z 3
可能有多个列,如列
a
,它们位于b
之前和之后。“我不认为这是一个普遍的解决办法。”复杂化现象-你们是对的,所以答案被编辑了。
>>> df.groupby('a').apply(lambda x:pd.Series(x.b[0], name='v'))
.rename_axis(['a','k']).reset_index()
a k v
0 1 a 1
1 1 b 2
2 2 k 4
3 2 v 6
4 3 z 3
df = pd.DataFrame({"a": [1, 2, 3], "b": [{"a": 1, "b": 2}, {"k": 4, "v": 6}, {"z": 3}]})
divider = df.columns.get_loc("b")
# expand dictionary within the `b` column
df["b"] = [tuple(entry.items()) for entry in df.b]
# merge dataframe before `b`, the exploded `b` column, and the dataframe after `b`
merger = (
df.iloc[:, :-divider],
df.b.explode().apply(pd.Series).set_axis(["k", "v"], axis=1),
df.iloc[:, : -(divider + 1)],
)
pd.concat(merger, axis=1)
a k v
0 1 a 1
0 1 b 2
1 2 k 4
1 2 v 6
2 3 z 3