Python Pandas-通过一些列名操作将多个值扩展到新列
我刚接触熊猫。Python Pandas-通过一些列名操作将多个值扩展到新列,python,python-3.x,pandas,Python,Python 3.x,Pandas,我刚接触熊猫。 考虑到你有一个状态,你有一个熊猫“代码>数据文件< /COD>下面的列结构: user_id | timestamp | foo_name1 | foo_name2 | foo_name3 正如我们所看到的,Dataframe有几个元数据参数,具有原始字符串值: 用户id,时间戳 还有几个动态名称列-每个列中都有一个json字符串值:foo_name1..foo_name3 foo_name1col中的json结构示例(具有固定的层次结构,dict键和值在其中可能有所不同): {
考虑到你有一个状态,你有一个熊猫“代码>数据文件< /COD>下面的列结构:
user_id | timestamp | foo_name1 | foo_name2 | foo_name3
正如我们所看到的,Dataframe
有几个元数据参数,具有原始字符串值:
用户id,时间戳
还有几个动态名称列-每个列中都有一个json字符串值:
foo_name1..foo_name3
foo_name1
col中的json结构示例(具有固定的层次结构,dict键和值在其中可能有所不同):
{“foo_att1”:“foo_value1”,“foo_att2”:“foo_value2”}
因此,我的意愿是以这种DF结构结束,而不是一种支出:DF:
user_id | timestamp | foo_name1-foo_att1 | foo_name1-foo_att2 | foo_name2-foo_att1 | foo_name2-foo_att2
而foo\u name1-foo\u att1
将具有as值:“foo\u value1”
foo\u name1-foo\u att2
将有值:“foo\u value2”
等等
我如何使用熊猫行动来实现这一点
pd.concat(axis=1)
和pd.json\u normalize()
dict
理解来命名列 userid timestamp foo_name1 foo_name2 foo_name3
94 2020-08-09 15:00:00 {'foo_att1': 1, 'foo_att2': 7} {'foo_att1': 5, 'foo_att2': 2} {'foo_att1': 5, 'foo_att2': 9}
61 2020-08-09 05:00:00 {'foo_att1': 2, 'foo_att2': 3} {'foo_att1': 10, 'foo_att2': 9} {'foo_att1': 10, 'foo_att2': 4}
69 2020-08-09 12:00:00 {'foo_att1': 9, 'foo_att2': 6} {'foo_att1': 7, 'foo_att2': 8} {'foo_att1': 5, 'foo_att2': 9}
16 2020-08-09 13:00:00 {'foo_att1': 2, 'foo_att2': 1} {'foo_att1': 7, 'foo_att2': 8} {'foo_att1': 9, 'foo_att2': 1}
51 2020-08-09 11:00:00 {'foo_att1': 3, 'foo_att2': 1} {'foo_att1': 7, 'foo_att2': 1} {'foo_att1': 6, 'foo_att2': 3}
userid timestamp foo_name1.foo_att1 foo_name1.foo_att2 foo_name2.foo_att1 foo_name2.foo_att2 foo_name3.foo_att1 foo_name3.foo_att2
94 2020-08-09 15:00:00 1 7 5 2 5 9
61 2020-08-09 05:00:00 2 3 10 9 10 4
69 2020-08-09 12:00:00 9 6 7 8 5 9
16 2020-08-09 13:00:00 2 1 7 8 9 1
51 2020-08-09 11:00:00 3 1 7 1 6 3
补充-选择候选列
选择要标准化的列的更好方法
df = pd.DataFrame([{**{"userid": random.randint(1,100),
"timestamp":dt.datetime(2020,8,9,random.randint(0,23))},
**{f"foo_name{f+1}":{f"foo_att{ff+1}":random.randint(1,10) for ff in range(2)} for f in range(3)},
**{"foo_namex":np.nan},
**{"foo_namey":"hello"}
} for r in range(5)])
# which columns do we want to convert?
convert = [c[0]
for c in df.dtypes.items()
if "foo" in c[0]
and c[1].name=="object"
and isinstance(df.loc[0,c[0]], dict)]
df2 = pd.concat([
df.loc[:,[c for c in df.columns if c not in convert]]] + # keep the columns not being converted
[
pd.DataFrame({f"{c}.{k}":v # rename columns as per requirement
for k,v in
# json_normalize is doing all the work, but requirement to rename columns....
pd.json_normalize(df[c]).to_dict(orient="list").items()})
# already worked out list of columns to convert
for c in convert
], axis=1)
@广黄:我看到你可能知道如何解决这些问题非常好,我在哪里可以学到这样的高级用法,在一些例外情况下?我只是阅读和吸收知识,加上30多年的编码。。。。核心是对数据结构和算法的理解,编写代码很简单。在
foo_nameX
值中,可能是Nan
值,而不是字典,我们是否有一个技巧来调整pd中k,v的。json_规范化(df[c])到dict(orient=“list”).items(),或者解决方法是不使用dict理解,而是在旧的方式循环中进行,并将其过滤掉?@Mulder做了额外的更新。显然,在选择列时,您可以更加保守。。。此更新只检查第一行中是否有一个dict
,而不是所有的行。我想我必须检查NaN
值,而不仅仅是给定列中的第一行,因为每个列可能都有多个原始值,其中一些Nan
有些不是这样,在这种情况下,我可能需要打开somhow来调整代码而不理解列表,并为列中的每一行检查这一点,或者我遗漏了什么?
df = pd.DataFrame([{**{"userid": random.randint(1,100),
"timestamp":dt.datetime(2020,8,9,random.randint(0,23))},
**{f"foo_name{f+1}":{f"foo_att{ff+1}":random.randint(1,10) for ff in range(2)} for f in range(3)},
**{"foo_namex":np.nan},
**{"foo_namey":"hello"}
} for r in range(5)])
# which columns do we want to convert?
convert = [c[0]
for c in df.dtypes.items()
if "foo" in c[0]
and c[1].name=="object"
and isinstance(df.loc[0,c[0]], dict)]
df2 = pd.concat([
df.loc[:,[c for c in df.columns if c not in convert]]] + # keep the columns not being converted
[
pd.DataFrame({f"{c}.{k}":v # rename columns as per requirement
for k,v in
# json_normalize is doing all the work, but requirement to rename columns....
pd.json_normalize(df[c]).to_dict(orient="list").items()})
# already worked out list of columns to convert
for c in convert
], axis=1)