我有像这样的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
指数无关紧要
如果我使用groupby('mat')['time']。对此df的sum()我会得到原始的df
,但我需要像groupby func的反转。
有没有办法让ungrouped
DataFrame的条件为time <= t
?
我正试图在这里使用循环,但它有点'unPythonic',有什么想法吗?
答案 0 :(得分:1)
使用循环的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
答案 1 :(得分:1)
您可.groupby('mat')
和.apply()
integer
除法和modulo
操作的组合使用cutoff
(10
)来分解每个time
{1}}值到所需的组件中:
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