我有两列,分别是开始和结束范围。我想为该列之间的范围设置虚拟列。我可以通过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)
答案 0 :(得分:3)
对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)