有没有办法更新pandas.pivot_table而不重建它?

时间:2015-07-31 22:41:28

标签: python pandas pivot-table

我的学生表包含student_idcourse_idexam_time(10k行)。我依靠student_idexam_time来获取会话或一天中的考试数量。我正在构建一个时间表启发式,可以一次更改一次考试时间,因此我需要多次更新此数据透视表。一门课程的考试时间的变化会影响原始数据帧中平均50行。有没有办法更新生成的数据透视表而不重新计算pandas中的整个事物,或者我应该自己跟踪数据透视表上的更改(即通过在更改的插槽中添加和减去1)?

编辑:这是我构建数据透视表的方法。我添加了一列来计算np.sum的数字。我找不到其他功能更快的功能。

sLength = len(df["student_id"])
df["ones"] = pd.Series(np.ones(sLength))
pivot_table = pd.pivot_table(df, rows = "student_id", cols = "exam_time", values = "ones", aggfunc = np.sum)

对于考试时间的变化,我写了这个(假设changed_courseold_slot移到new_slot

affected_students = df[df["course_id"] == changed_course]["student_id"]
pivot_table[old_slot][affected_students] -= 1
pivot_table[new_slot][affected_students] += 1

1 个答案:

答案 0 :(得分:1)

以下是示例代码,其思路是通过减去旧行的数据透视表来更新总数据透视表,并添加新行的数据透视表。

因此,每次更改数据时,您都会调用两次pivot_table(),一次add()和一次sub()

import numpy as np
import pandas as pd

### create random data
N = 1000
a = np.random.randint(0, 100, N)
b = np.random.randint(0, 30, N)
c = np.random.randint(0, 10, N)

df = pd.DataFrame({"a":a, "b":b, "c":c})

### calculate pivot sum
res = df.pivot_table(values="c", index="a", columns="b", aggfunc="sum", fill_value=0)

### create random rows to change
M = 100
row_index = np.unique(np.random.randint(0, N, M))
old_rows = df.iloc[row_index]
M = old_rows.shape[0]
new_rows = pd.DataFrame({"a":np.random.randint(0, 100, M), 
                         "b":np.random.randint(0, 30, M),
                         "c":np.random.randint(0, 10, M)})

### update pivot table
sub_df = old_rows.pivot_table(values="c", index="a", columns="b", aggfunc="sum", fill_value=0)
add_df = new_rows.pivot_table(values="c", index="a", columns="b", aggfunc="sum", fill_value=0)
new_res = res.sub(sub_df, fill_value=0).add(add_df, fill_value=0)

### check result
df.iloc[row_index] = new_rows.values
res2 = df.pivot_table(values="c", index="a", columns="b", aggfunc="sum", fill_value=0)
print new_res.astype(int).equals(res2)