能否用比下面更多的Pythonic代码在Pandas中一次性完成以下操作?
我在pandas-dataframe中有一行:
None
的形式传递)'c.x', 'c.y', 'c.z'
应该未展平,即使用键c
转换为子项x, y, z
。同样,应删除每行中的NaN键。示例输入:我用row = next(df.iterrows())
遍历数据帧中的行,其中示例行看起来像:
a 3
b NaN
c.x 4
c.y 5
c.z NaN
所需的输出
{"A": 3,
"C": {"X": 4, "Y": 5}}
(对我来说,最自然的方法是这样的:
outdict={"A": row['a'] if not pandas.isna(row['a']) else None,
"B": row['b'] if not pandas.isna(row['b']) else None,
"C": {"X": row['c.x'] if not pandas.isna(row['c.x']) else None,
"Y": row['c.y'] if not pandas.isna(row['c.y']) else None,
"Z": row['c.z'] if not pandas.isna(row['c.z']) else None
}}
但是,这仍然将None
分配给我想保留为空的插槽(接收应用程序在处理nulls
时很困难。]
一种解决方法是使用此代码,然后在第二遍中删除所有None值,或者我可以对每个值使用outdict.update
(如果值为NaN
,则不更新)。但是这两种解决方案对我来说似乎都不是很有效。
要将DataFrame转换为不带NaN的字典,有一种简单的方法:
df.dropna().to_dict()
但是您也想从组合键创建子词典,我发现除了循环之外别无他法:
df = DataFrame({"col": [3, None, 4, 5, None]}, index=["a", "b", "c.x", "c.y", "c.z"])
d = df.dropna().to_dict()
d
是:
{'col': {'a': 3.0, 'c.x': 4.0, 'c.y': 5.0}}
然后:
d2 = dict()
for k, v in d['col'].items():
if k.count('.'):
a, b = k.split('.')
d2.setdefault('a', {})
d2[a][b] = v
else:
d2[k] = v
[d2
是:
{'a': 3.0, 'c': {'y': 5.0, 'x': 4.0}}
如果row
是Series
对象,则以下代码将不会为NaN创建任何条目:
outdict = {row.index[i]: row[i]
for i in range(data.shape[1])
if not pandas.isna(row[i])}
但是,它不会创建您想要的嵌套结构。我有几种方法可以解决此问题,但没有一种方法非常优雅。我能想到的最好方法是在创建a.b
时排除带有outdict
形式标签的列; 即
outdict = {row.index[i]: row[i]
for i in range(data.shape[1])
if not (pandas.isna(row[i]) or '.' in row.index[i])}
然后分别创建下标并将其分配给下标。