Python 扩展数据帧值的更快方法

Python 扩展数据帧值的更快方法,python,pandas,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

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

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年。我现在就是这样做的。(对于大数据帧来说速度很慢)


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

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

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
这将在创建新数据框时节省时间,但您仍然需要更改年份列。这可以通过改变年份来实现,并且可以通过一次操作实现,如下所示

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

基本上,您创建的是一个包含年份的列表,重复初始数据帧的长度。

每次追加时,您创建的是一个新的副本,成本很高。如果在一次操作中连接所有数据帧,可能会获得一些时间

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
这将在创建新数据框时节省时间,但您仍然需要更改年份列。这可以通过改变年份来实现,并且可以通过一次操作实现,如下所示

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

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

使用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]})

使用numpy平铺并重复

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]})