划分 python pandas DataFrame 的行

Divide rows of python pandas DataFrame

我有一个 pandas DataFrame df 像这样

   mat  time
0  101   20
1  102    7
2  103   15

我需要划分行,这样时间列中的任何值都不会高于 t=10 才能得到类似这样的东西

   mat  time
0  101   10
2  101   10
3  102    7
4  103   10
5  103    5

索引无关紧要

如果我在这个 df 上使用 groupby('mat')['time'].sum() 我会得到原来的 df,但我需要像groupby 函数。

有什么办法可以得到条件为time <= tungrouped DataFrame吗?

我想在这里使用一个循环,但有点 'unPythonic',有什么想法吗?

使用一个 apply 函数循环直到所有值都小于 10。

def split_max_time(df):
    new_df = df.copy()
    while new_df.iloc[-1, -1] > 10:
        temp = new_df.iloc[-1, -1]
        new_df.iloc[-1, -1] = 10
        new_df = pd.concat([new_df, new_df])
        new_df.iloc[-1, -1] = temp - 10
    return new_df


print df.groupby('mat', group_keys=False).apply(split_max_time)

   mat  time
0  101    10
0  101    10
1  102     7
2  103    10
2  103     5

您可以 .groupby('mat').apply() 组合 integer 除法和 modulo 运算使用 cutoff (10) 分解每个 time 值转换成所需的组件:

cutoff = 10
def decompose(time):
    components = [cutoff for _ in range(int(time / cutoff))] + [time.iloc[0] % cutoff]
    return pd.Series([c for c in components if c > 0])

df.groupby('mat').time.apply(decompose).reset_index(-1, drop=True)

得到:

mat
101    10
101    10
102     7
103    10
103     5

如果您关心性能:

%timeit df.groupby('mat', group_keys=False).apply(split_max_time)
100 loops, best of 3: 4.21 ms per loop

%timeit df.groupby('mat').time.apply(decompose).reset_index(-1, drop=True)
1000 loops, best of 3: 1.83 ms per loop