gpt4 book ai didi

python - 如何获取 Pandas Dataframe 中的行并将其转换为列的值?

转载 作者:太空宇宙 更新时间:2023-11-04 05:37:57 24 4
gpt4 key购买 nike

我不确定如何真正准确地描述这个问题,所以我将在下面添加更多细节并提供一个可重现的示例。

基本上,我在 Pandas 数据框中有两列和多行,我希望能够在构建新列的位置进行转换,以指示给定单元至少存在一个值。

例如,假设我有一个包含两列的 pandas 数据框:学生和他们参加的类(class)。假设我还有一本字典,将每个类映射到一个主题。我想创建一个新的数据框,其中一列用于 studentid,一列用于每个主题。一个科目的每一列都会告诉我学生是否至少上过该科目的一门课(因此最终表在学生级别是唯一的)。例如:

import pandas as pd
s = {'student_id' : pd.Series(['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']),
'classes' : pd.Series(['Algebra', 'Geometry', 'Topology', 'Intro to Python', 'Biology', 'Chemistry', 'Algebra',
'Intro to Java', 'Chinese 101'])}
c = {'subject' : pd.Series(['Math', 'Math', 'Math', 'CS', 'Science', 'Science', 'CS', 'Languages']),
'classes' : pd.Series(['Algebra', 'Geometry', 'Topology', 'Intro to Python', 'Biology', 'Chemistry',
'Intro to Java', 'Chinese 101'])}
students = pd.DataFrame(s, columns = ['student_id', 'classes'])

此代码的输出将是(抱歉,不确定如何在 StackOverflow 中创建表,所以我只是将其作为代码)。

students

student_id classes
0 A Algebra
1 A Geometry
2 A Topology
3 B Intro to Python
4 B Biology
5 B Chemistry
6 C Algebra
7 C Intro to Java
8 C Chinese 101

classes

subject classes
0 Math Algebra
1 Math Geometry
2 Math Topology
3 CS Intro to Python
4 Science Biology
5 Science Chemistry
6 CS Intro to Java
7 Languages Chinese 101

现在,我想创建一个新的数据框,它基本上是 students 数据框的转换,它为 classes 数据框中的每个主题添加新列。更准确地说,我想要一个新的数据框,可能标题为 student_classes 在 student_id 级别是唯一的,并且如果他们至少上过一次课,则该主题的列中的值为 1在那个主题中。按照这个例子,我想:

 student_id  Math  CS  Science   Languages
0 A 1 0 0 0
1 B 0 1 1 0
2 C 1 1 0 1

下面是我为解决这个特定示例所做的工作。问题是我的实际数据与学生无关,数据帧要大得多,这使得以下解决方案非常慢且内存密集。事实上,我的 iPython Notebook 在我更大的表上返回内存错误。

所以,我实际上做的是创建一个字典的字典

classes_subject_dict={'Math': {'Algebra':1,
'Geometry':1,
'Topology':1,
},
'CS': {'Intro to Python':1,
'Intro to Java':1,
},
'Science':{'Biology':1,
'Chemistry':1,
},
'Languages':{'Chinese 101':1
}
}

然后,我查看字典中的键,并使用 map 方法(功能?我不确定这里的技术术语是什么)将 1 的值映射到定义的列如果出现合适的类,则由主题:

for key in classes_subject_dict.keys():
students[key]=students.classes.map(classes_subject_dict[key])

然后,我取每列中的最大值,删除 classes 列,然后删除重复项以获得我的最终表

for key in classes_subject_dict.keys():
students[key]=students.groupby(['student_id'])[key].transform(max)

students = students.drop('classes', 1)
students = students.drop_duplicates()
students = students.fillna(0)

students

student_id CS Languages Math Science
0 A 0 0 1 0
3 B 1 0 0 1
6 C 1 1 1 0

同样,这对于这个特定的简单示例来说效果很好,但我的实际数据在长度和宽度方面都要大得多。虽然我的实际数据与学生没有任何关系,但类似的描述是我有 300 个“科目”和数十万个“学生”。我注意到使用 map 方法确实会降低我的代码速度,我想知道是否有更有效的方法来执行此操作。

最佳答案

您可以使用 merge , crosstab然后 astype :

import pandas as pd
import pandas as pd
s = {'student_id' : pd.Series(['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']),
'classes' : pd.Series(['Algebra', 'Geometry', 'Topology', 'Intro to Python', 'Biology', 'Chemistry', 'Algebra',
'Intro to Java', 'Chinese 101'])}
c = {'subject' : pd.Series(['Math', 'Math', 'Math', 'CS', 'Science', 'Science', 'CS', 'Languages']),
'classes' : pd.Series(['Algebra', 'Geometry', 'Topology', 'Intro to Python', 'Biology', 'Chemistry',
'Intro to Java', 'Chinese 101'])}
students = pd.DataFrame(s, columns = ['student_id', 'classes'])
classes = pd.DataFrame(c, columns = ['subject', 'classes'])
print students
student_id classes
0 A Algebra
1 A Geometry
2 A Topology
3 B Intro to Python
4 B Biology
5 B Chemistry
6 C Algebra
7 C Intro to Java
8 C Chinese 101

print classes
subject classes
0 Math Algebra
1 Math Geometry
2 Math Topology
3 CS Intro to Python
4 Science Biology
5 Science Chemistry
6 CS Intro to Java
7 Languages Chinese 101
df = pd.merge(students, classes, on=['classes'])
print df
student_id classes subject
0 A Algebra Math
1 C Algebra Math
2 A Geometry Math
3 A Topology Math
4 B Intro to Python CS
5 B Biology Science
6 B Chemistry Science
7 C Intro to Java CS
8 C Chinese 101 Languages

df = pd.crosstab(df['student_id'], df['subject'])
print df
subject CS Languages Math Science
student_id
A 0 0 3 0
B 1 0 0 2
C 1 1 1 0

df = (df > 0)
print df
subject CS Languages Math Science
student_id
A False False True False
B True False False True
C True True True False
df = (df > 0).astype(int)
print df
subject CS Languages Math Science
student_id
A 0 0 1 0
B 1 0 0 1
C 1 1 1 0

关于python - 如何获取 Pandas Dataframe 中的行并将其转换为列的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35029258/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com