更快地扩展pandas Dataframe的值

时间:2017-03-14 20:21:47

标签: python pandas

假设我有一个这样的数据帧。

df = pd.DataFrame(  data    = np.random.random( (10,3) ), 
                    columns = [ 'Year', 'Var1', 'Var2' ], 
                    index   = np.arange(10) )
df.Year = np.repeat( [2000, 2001], 5 )

>>> df
   Year      Var1      Var2
0  2000  0.811247  0.483376
1  2000  0.707072  0.514624
2  2000  0.457840  0.246798
3  2000  0.000576  0.105618
4  2000  0.825557  0.044757
5  2001  0.350272  0.406710
6  2001  0.176377  0.084755
7  2001  0.039902  0.510173
8  2001  0.631718  0.136885
9  2001  0.441104  0.831035

我想获取2001年的值并重复它们直到2200.这就是我目前这样做的方式。 (对于大型数据帧来说速度很慢)

df2001 = df[ df.Year == 2001 ]
extensionRange = np.arange( 2002, 2200 + 1 )
for year in extensionRange:
    df2001.Year = year
    df = df.append( df2001 )

>>> df.tail(10)
     Year      Var1      Var2
5  2199.0  0.350272  0.406710
6  2199.0  0.176377  0.084755
7  2199.0  0.039902  0.510173
8  2199.0  0.631718  0.136885
9  2199.0  0.441104  0.831035
5  2200.0  0.350272  0.406710
6  2200.0  0.176377  0.084755
7  2200.0  0.039902  0.510173
8  2200.0  0.631718  0.136885
9  2200.0  0.441104  0.831035

我的实际数据框要大得多,此过程大约需要1分钟才能完成。有更快的方法吗?也许没有追加?

2 个答案:

答案 0 :(得分:0)

每次你追加你都要创建一个昂贵的新副本。如果您在一次操作中连接所有数据帧,则可能会获得一些时间。

new_df = pd.concat([df] * len(np.arange(2002, 2200 + 1 )))

%timeit new_df = pd.concat([df] * len(np.arange(2002, 2200 + 1 )))
100 loops, best of 3: 20.5 ms per loop

这将节省创建新数据框的时间,但您仍需要更改Year列。这可以通过简单地改变年份来实现,并且可以在一个操作中实现,如下所示

import itertools
years = [[year]*len(df) for year in np.arange(2002, 2200 + 1 )]
new_df['Year'] = itertools.chain(*years)

%timeit new_df['Year'] = itertools.chain(*[[year]*len(df) for year in np.arange(2002, 2200 + 1 )])
1000 loops, best of 3: 424 µs per loop

您基本上是在创建一个列表,其中年份重复初始数据框的长度。

答案 1 :(得分:0)

使用numpy tile并重复

df = pd.DataFrame(data = np.random.random((10,3)),
                  columns = ['Year','Var1','Var2'],
                  index = np.arange(10))
df.Year = np.repeat([2000, 2001], 5)

# assign variables
max_year = 2200
unique_year = 2000
rows_each_year = 5

year_clone_count = max_year - unique_year
# grab values from input dataframe as numpy arrays, tile values to repeat
base = df[df.Year == unique_year][['Var1', 'Var2']].values
extended = np.tile(df[df.Year == unique_year + 1][['Var1', 'Var2']].values.T,
                   year_clone_count).T

# join non-repeat data with repeated data
data = np.concatenate((base, extended))

# make year column
year_col = np.repeat(range(unique_year, max_year + 1),
                     rows_each_year)

# create dataframe
df_out = pd.DataFrame({'Year': year_col,
                       'Var1': data[:, 0],
                       'Var2': data[:, 1]})