我有两列有开始和结束范围.我想为这列之间的范围制作虚拟列.我可以通过apply方法制作它,但它很慢.我可以不申请(因为我有~2-5M行).
整个DataFrame:
start end
0 36 36
1 31 31
2 29 29
3 10 10
4 35 35
5 42 44
6 24 26
我想看到的:
start end 8 9 10 24 25 26 29 31 35 36 42 43 44
0 36 36 NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN
1 31 31 NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN
2 29 29 NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN
3 10 10 NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 35 35 NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
5 42 44 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 1.0 1.0
6 24 26 NaN NaN NaN 1.0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN
7 25 25 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN
8 35 35 NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
9 8 10 1.0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
现在我使用这段代码:
import itertools
def zip_with_scalar(l, o):
return dict(zip(l, itertools.repeat(o)))
df.merge(df.apply(lambda s: pd.Series(zip_with_scalar(range(s['start'], s['end']+1), 1)), axis = 1), left_index=True, right_index=True)
解决方法:
使用列表理解与DataFrame构造函数:
a = [dict.fromkeys(range(x, y), 1) for x, y in zip(df['start'], df['end']+1)]
df = df.join(pd.DataFrame(a, index=df.index))
print (df)
start end 10 24 25 26 29 31 35 36 42 43 44
0 36 36 NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN
1 31 31 NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN
2 29 29 NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN
3 10 10 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 35 35 NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN
5 42 44 NaN NaN NaN NaN NaN NaN NaN NaN 1.0 1.0 1.0
6 24 26 NaN 1.0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN
性能:
#[70000 rows x 2 columns]
df = pd.concat([df] * 10000, ignore_index=True)
def a(df):
a = [dict.fromkeys(range(x, y), 1) for x, y in zip(df['start'], df['end']+1)]
return df.join(pd.DataFrame(a, index=df.index))
import itertools
def zip_with_scalar(l, o):
return dict(zip(l, itertools.repeat(o)))
def b(df):
return df.merge(df.apply(lambda s: pd.Series(zip_with_scalar(range(s['start'], s['end']+1), 1)), axis = 1), left_index=True, right_index=True)
In [176]: %timeit a(df.copy())
202 ms ± 6.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [177]: %timeit b(df.copy())
38.9 s ± 1.19 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。