pandas 中列表与列表列表之间比较的向量化

Vectorisation of comparison between a list and a list of lists in pandas

我有两个pd.DataFramesclasses老师

classes DataFrame 包含变量 classes['no-pupils']classes['teachers']。第一个是整数(注册学生的数量),第二个是字符串列表,因为每个 class 可以有几个老师。

teachers DataFrame 有(除其他外)两个变量。第一个是对应于 classes['teachers'] 列表的 teachers[[=​​52=]]项,第二个是我要计算的 teachers[[=​​50=]]

我想通过将 [=] 所在的所有行的 classes['no-pupils'] 60=]es['teachers'] 包含 teachers[[=​​52=]] 以计算教师与多少学生互动。

现在,我通过使用 for 循环遍历教师 DataFrame 并在该循环中使用以下代码遍历 classes DataFrame 来执行此操作:

for index-teacher, teacher in teachers.iterrows():
    for index-class, class in classes.iterrows():
        if teacher['name'] in class['teachers']:
            teachers['no-pupils'][index-teacher] = teachers['no-pupils'][index1] + classes['no-pupils'][index-class]

由于每个 DataFrame 大约有 2000 行,因此这很容易花费 5-10 分钟。因此我想知道是否有一种计算效率更高的方法,使用来自 pandas.

的强大矢量化功能

P.S.: 如果你想知道奇怪的用例,我认为是因为我不能透露真正的用例。

您不需要检查每个教师的整个数据框,您可以 pre-process 它并在一次数据框迭代中为所有教师构建所需的数据。我建议你使用 Python defaultdicts:

from collections import defaultdict

df = pd.DataFrame({
    'teachers': [['A', 'C'], ['C', 'E'], ['A', 'B', 'C'], ['D'], ['B', 'E']],
    'pupils': [1, 2, 3, 4, 5]
})

t_pupils = defaultdict(int)
for i, row in df.iterrows():
    for teacher in row['teachers']:
        t_pupils[teacher] += row['pupils']
t_pupils

returns:

defaultdict(int, {'A': 4, 'B': 8, 'C': 6, 'D': 4, 'E': 7})

这样您将用线性代替二次复杂度,这将大大提高您的性能。