我陷入了死胡同,而且我正在使用一些代码,这些代码绝对不是熊猫,因为在Pandas中这应该是一项非常简单的任务。我确定有更好的方法。
我有一个DataFrame,我将从中提取一行并创建一个新的DataFrame,如下所示:
>>> sampledata
float_col int_col str_col r v new_coltest eddd
0 0.1 1 a 5 1.0 0.1 -0.539783
1 0.2 2 b 5 NaN 0.2 -1.394550
2 0.2 6 None 5 NaN 0.2 0.290157
3 10.1 8 c 5 NaN 10.1 -1.799373
4 NaN -1 a 5 NaN NaN 0.694682
>>> newsampledata = sampledata[(sampledata.new_coltest == 0.1) & (sampledata.float_col == 0.1)]
>>> newsampledata
float_col int_col str_col r v new_coltest eddd
0 0.1 1 a 5 1.0 0.1 -0.539783
我想要做的是将这一行复制到" newsampledata" n次,其中n是已知整数。理想情况下,具有n行的最终DataFrame将覆盖单行" newsampledata"但这在任何方面都不重要。
我目前正在使用for循环执行pd.concat
n-1次以便填充DataFrame,但由于concat
的工作方式,这并不快。我也使用append
尝试了相同类型的策略,这比concat
略慢。
我已经看到了一些关于类似项目的其他问题,但很多人之前没有看过这个问题。此外,由于性能问题,我已经远离地图/应用,但如果您已经看到这种方法的良好表现,请告诉我,我也会尝试。
TIA
答案 0 :(得分:6)
我想你可以sample
替换
newsampledata.sample(n, replace=True).reset_index(drop=True)
或reindex
newsampledata.reindex(newsampledata.index.repeat(n)).reset_index(drop=True)
答案 1 :(得分:4)
您可以使用DataFrame
构造函数:
N = 10
df =pd.DataFrame(newsampledata.values.tolist(),index=np.arange(N),columns=sampledata.columns)
print (df)
float_col int_col str_col r v new_coltest eddd
0 0.1 1 a 5 1.0 0.1 -0.539783
1 0.1 1 a 5 1.0 0.1 -0.539783
2 0.1 1 a 5 1.0 0.1 -0.539783
3 0.1 1 a 5 1.0 0.1 -0.539783
4 0.1 1 a 5 1.0 0.1 -0.539783
5 0.1 1 a 5 1.0 0.1 -0.539783
6 0.1 1 a 5 1.0 0.1 -0.539783
7 0.1 1 a 5 1.0 0.1 -0.539783
8 0.1 1 a 5 1.0 0.1 -0.539783
9 0.1 1 a 5 1.0 0.1 -0.539783
print (df.dtypes)
float_col float64
int_col int64
str_col object
r int64
v float64
new_coltest float64
eddd float64
dtype: object
<强>计时强>:
在大型DataFrame
构造函数方法中,小sample
是更快reindex
和DataFrame
方法。
N = 1000
In [88]: %timeit (pd.DataFrame(newsampledata.values.tolist(), index=np.arange(N), columns=sampledata.columns))
1000 loops, best of 3: 745 µs per loop
In [89]: %timeit (newsampledata.sample(N, replace=True).reset_index(drop=True))
The slowest run took 4.88 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 470 µs per loop
In [90]: %timeit (newsampledata.reindex(newsampledata.index.repeat(N)).reset_index(drop=True))
1000 loops, best of 3: 476 µs per loop
N = 10000
In [92]: %timeit (pd.DataFrame(newsampledata.values.tolist(), index=np.arange(N), columns=sampledata.columns))
1000 loops, best of 3: 946 µs per loop
In [93]: %timeit (newsampledata.sample(N, replace=True).reset_index(drop=True))
1000 loops, best of 3: 775 µs per loop
In [94]: %timeit (newsampledata.reindex(newsampledata.index.repeat(N)).reset_index(drop=True))
1000 loops, best of 3: 827 µs per loop
N = 100000
In [97]: %timeit (pd.DataFrame(newsampledata.values.tolist(), index=np.arange(N), columns=sampledata.columns))
The slowest run took 12.98 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 6.93 ms per loop
In [98]: %timeit (newsampledata.sample(N, replace=True).reset_index(drop=True))
100 loops, best of 3: 7.07 ms per loop
In [99]: %timeit (newsampledata.reindex(newsampledata.index.repeat(N)).reset_index(drop=True))
100 loops, best of 3: 7.87 ms per loop
N = 10000000
In [83]: %timeit (pd.DataFrame(newsampledata.values.tolist(), index=np.arange(N), columns=sampledata.columns))
1 loop, best of 3: 589 ms per loop
In [84]: %timeit (newsampledata.sample(N, replace=True).reset_index(drop=True))
1 loop, best of 3: 757 ms per loop
In [85]: %timeit (newsampledata.reindex(newsampledata.index.repeat(N)).reset_index(drop=True))
1 loop, best of 3: 731 ms per loop
答案 2 :(得分:2)
我认为你可以在不使用for循环的情况下使用concat。
df = pd.DataFrame({'a':[1], 'b':[.1]})
repetitions = 4
res = pd.concat([df]*repetitions)
print(res)
输出
a b
0 1 0.1
0 1 0.1
0 1 0.1
0 1 0.1
所以在我的样本框架上,这确实比使用for循环要快大约5倍。但是,我期望不使用concat的不同解决方案明显更快。
答案 3 :(得分:1)