我有一个更复杂的情况,数据集具有嵌套结构:
import json
data = '{"TextID":{"0":"0038f0569e","1":"003eb6998d","2":"006da49ea0"},"Summary":{"0":{"Crisis_Level":["c"],"Type":["d"],"Special_Date":["a"]},"1":{"Crisis_Level":["d"],"Type":["a","d"],"Special_Date":["a"]},"2":{"Crisis_Level":["d"],"Type":["a"],"Special_Date":["a"]}}}'
df = pd.DataFrame.from_dict(json.loads(data))
print(df)
输出:
TextID Summary
0 0038f0569e {'Crisis_Level': ['c'], 'Type': ['d'], 'Specia...
1 003eb6998d {'Crisis_Level': ['d'], 'Type': ['a', 'd'], 'S...
2 006da49ea0 {'Crisis_Level': ['d'], 'Type': ['a'], 'Specia...
Summary
列包含字典对象,因此我使用apply
与from_dict
和stack
来提取每个字典的每一行:
df2 = df.apply(
lambda x: pd.DataFrame.from_dict(x[1], orient='index').stack(), axis=1)
print(df2)
输出:
Crisis_Level Special_Date Type
0 0 0 1
0 c a d NaN
1 d a a d
2 d a a NaN
看起来不错,但缺少TextID
列。为了恢复TextID
列,我尝试了三种方法:
修改 apply
函数以返回多列:
df_tmp = df.copy()
df_tmp[['TextID', 'Summary']] = df.apply(
lambda x: pd.Series([x[0], pd.DataFrame.from_dict(x[1], orient='index').stack()]), axis=1)
print(df_tmp)
输出结果为:
TextID Summary
0 0038f0569e Crisis_Level 0 c
Type 0 d
Spec...
1 003eb6998d Crisis_Level 0 d
Type 0 a
...
2 006da49ea0 Crisis_Level 0 d
Type 0 a
Spec...
但这不是我想要的,Summary
的结构被展平了。
使用 pd.concat
:
df_tmp2 = pd.concat([df['TextID'], df2], axis=1)
print(df_tmp2)
输出结果为:
TextID (Crisis_Level, 0) (Special_Date, 0) (Type, 0) (Type, 1)
0 0038f0569e c a d NaN
1 003eb6998d d a a d
2 006da49ea0 d a a NaN
看起来很好,MultiIndex
列结构被保留为元组。但是检查一下列的类型:
df_tmp2.columns
输出结果为:
Index(['TextID', ('Crisis_Level', 0), ('Special_Date', 0), ('Type', 0),
('Type', 1)],
dtype='object')
只是一个普通的 Index
类,而不是 MultiIndex
类。
使用 set_index
:
将所有要保留的列转换为行索引,经过一些复杂的 apply
函数,然后使用 reset_index
恢复列:
df_tmp3 = df.set_index('TextID')
df_tmp3 = df_tmp3.apply(
lambda x: pd.DataFrame.from_dict(x[0], orient='index').stack(), axis=1)
df_tmp3 = df_tmp3.reset_index(level=0)
print(df_tmp3)
输出结果为:
TextID Crisis_Level Special_Date Type
0 0 0 1
0 0038f0569e c a d NaN
1 003eb6998d d a a d
2 006da49ea0 d a a NaN
检查一下列的类型:
df_tmp3.columns
输出结果为:
MultiIndex(levels=[['Crisis_Level', 'Special_Date', 'Type', 'TextID'], [0, 1, '']],
codes=[[3, 0, 1, 2, 2], [2, 0, 0, 0, 1]])
所以,如果你的apply
函数将返回MultiIndex
列,并且你想要保留它,那么你可能想尝试第三种方法。
df.ix[:, 10:16]
。我觉得你需要将特征与数据集进行合并。 - Zelazny7