Python 熊猫把字典分解成几行
我有一个数据帧:Python 熊猫把字典分解成几行,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个数据帧: Name Sub_Marks 0 Tom {'Maths': 30, 'English': 40, 'Science': 35} 1 Harry {'Maths': 35, 'English': 30, 'Science': 25} 2 Nick {'Maths': 32, 'English': 23, 'Science': 20} 我需要把字典分解成多行。例如 Name
Name Sub_Marks
0 Tom {'Maths': 30, 'English': 40, 'Science': 35}
1 Harry {'Maths': 35, 'English': 30, 'Science': 25}
2 Nick {'Maths': 32, 'English': 23, 'Science': 20}
我需要把字典分解成多行。例如
Name Subject Marks
0 Tom Maths 30
1 Tom English 40
2 Tom Science 35
3 Harry Maths 35
4 Harry English 30
5 Harry Science 25
6 Nick Maths 32
7 Nick English 23
8 Nick Science 20
我知道我们可以在数据框中分解列表。使用字典有什么方法吗?您可以使用将字典“分解”为列,然后使用将列转换为主题
和标记
列,如下所示:
(df.drop(columns='Sub_Marks')
.join(df.apply(lambda x: pd.Series(x['Sub_Marks']), axis=1))
.melt(id_vars='Name', value_vars=['Maths', 'English', 'Science'], var_name='Subject', value_name='Marks')
.sort_values('Name')
).reset_index(drop=True)
您还可以使用pd.DataFrame()
和to_list()
来“分解”字典:
(df.join(pd.DataFrame(df.pop('Sub_Marks').to_list()))
.melt(id_vars='Name', value_vars=['Maths', 'English', 'Science'], var_name='Subject', value_name='Marks')
.sort_values('Name')
).reset_index(drop=True)
输出:
Name Subject Marks
0 Harry Maths 35
1 Harry English 30
2 Harry Science 25
3 Nick Maths 32
4 Nick English 23
5 Nick Science 20
6 Tom Maths 30
7 Tom English 40
8 Tom Science 35
我们可以通过迭代列表中dataframe的值来创建一个包含
名称
、标记
和主题
的元组列表,然后我们可以从这个元组列表中创建一个新的dataframe
out = pd.DataFrame([(n, k, v) for (n, d) in df.values for k, v in d.items()])
out.columns = ['Name', 'Subject', 'Marks']
备选pandas
方法
m = pd.DataFrame([*df['Sub_Marks']], df.index).stack()\
.rename_axis([None,'Subject']).reset_index(1, name='Marks')
out = df[['Name']].join(m)
您可以仅从
字典中提取值,然后将其展开为多列,如下所示:
data = {'Name' : ['Tom', "Harry", "Nick"], "Sub_Marks" : [{'Maths': 30, 'English': 40, 'Science': 35},{'Maths': 35, 'English': 42, 'Science': 31},{'Maths': 20, 'English': 14, 'Science': 65}]}
df = pd.DataFrame(data)
df[['Maths','English', 'Science']] = df['Sub_Marks'].apply(pd.Series)
df.drop(columns=['Sub_Marks'], inplace=True)
df = df.set_index('Name').stack().reset_index()
df.columns = ['Name', 'Subject', 'Marks']
通过explode
-
df['Marks'] = df['Sub_Marks'].apply(lambda x: x.values())
df = df.apply(pd.Series.explode).rename(columns = {'Sub_Marks': 'Subject'})
您可能需要首先使用ast.literal\u eval
(如果上述方法不起作用)-
哇!我喜欢你的解决方案。那个拆包很聪明。你可以解释一下*df['Sub_Marks']
部分发生了什么吗?*
用于将列Sub_Marks
解包为列表
,因此,除了使用[*df['Sub_Marks']
之外,你还可以使用列表(df['Sub_Marks']))
无需使用apply
+dict.values
,从字典列表创建一个新的数据帧会自动处理该问题;)@ShubhamSharma哦。我不确定它是否有,因为它在专栏中仍然向我显示了一个dict。但是,apply(pd.Series)
也可以工作。pd.DataFrame(list(df['Sub_Marks'))
将字典列表扩展到一个数据框架中,其中该框架中的列名对应字典列表中的所有唯一键,一般来说,你应该避免使用apply
+pd.Series
,因为这是一个计算成本更高的操作:)啊,我知道了。我想我之前误解了。另外,我不知道apply
+pd.Series
在计算上很昂贵。谢谢你,先生:)
df['Marks'] = df['Sub_Marks'].apply(lambda x: x.values())
df = df.apply(pd.Series.explode).rename(columns = {'Sub_Marks': 'Subject'})
import ast
df['Sub_Marks'] = df['Sub_Marks'].apply(ast.literal_eval)