Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数据帧的矢量化_Python_Pandas_For Loop_Vectorization - Fatal编程技术网

Python 数据帧的矢量化

Python 数据帧的矢量化,python,pandas,for-loop,vectorization,Python,Pandas,For Loop,Vectorization,假设以下简化框架: 我有一个由100行、4个类和每个实例的4个特征组成的参数的3D数据帧: iterables = [list(range(100)), [0,1,2,3]] index = pd.MultiIndex.from_product(iterables, names=['instances', 'classes']) columns = ['a', 'b', 'c', 'd'] np.random.seed(42) parameters = pd.DataFrame(np.rando

假设以下简化框架:

我有一个由100行、4个类和每个实例的4个特征组成的参数的3D数据帧:

iterables = [list(range(100)), [0,1,2,3]]
index = pd.MultiIndex.from_product(iterables, names=['instances', 'classes'])
columns = ['a', 'b', 'c', 'd']
np.random.seed(42)
parameters = pd.DataFrame(np.random.randint(1, 2000, size=(len(index), len(columns))), index=index, columns=columns)

parameters

instances classes   a     b     c     d                     
0         0        1127  1460   861  1295
          1        1131  1096  1725  1045
          2        1639   122   467  1239
          3         331  1483    88  1397
1         0        1124   872  1688   131
...                 ...   ...   ...   ...
98        3        1321  1750   779  1431
99        0        1793   814  1637  1429
          1        1370  1646   420  1206
          2         983   825  1025  1855
          3        1974   567   371   936
df
成为一个数据帧,对于每个实例和每个特性(列),报告观察到的类

np.random.seed(42)
df = pd.DataFrame(np.random.randint(0, 3, size=(100, len(columns))), index=list(range(100)), 
                  columns=columns)
    a  b  c  d
0   2  0  2  2
1   0  0  2  1
2   2  2  2  2
3   0  2  1  0
4   1  1  1  1
.. .. .. .. ..
95  1  2  0  1
96  2  1  2  1
97  0  0  1  2
98  0  0  0  1
99  1  2  2  2
我想创建第三个数据框(我们称之为
new_df
),形状为(100,4),包含数据框
参数中的参数,基于数据框
df
上观察到的类

例如,在第一列(a)的
df的第一行中,我观察到类2,因此我感兴趣的值是
参数的第一个实例中的第二个类,即1127,它将填充
新df的第一行和列。按照这种方法,列“b”的第一个观察值是0级,因此在第一行中,新_df的列b我希望观察1460,依此类推

使用for循环,我可以获得所需的结果:

new_df = pd.DataFrame(0, index=list(range(100)), columns=columns) # initialize the df
for i in range(len(df)):
    for c in df.columns:
        new_df.iloc[i][c] = parameters.loc[i][c][df.iloc[i][c]]

new_df

    a     b      c    d
0   1639  1460   467  1239
1   1124   872   806   344
2   1083   511  1706  1500
3    958  1155  1268   563
4     14   242   777  1370
..   ...   ...   ...   ...
95  1435  1316  1709   755
96   346   712   363   815
97  1234   985   683  1348
98   127  1130  1009  1014
99  1370   825  1025  1855
然而,原始数据集包含数百万行和数百列,继续for循环是不可行的


有没有办法将这样的问题矢量化以避免for循环?(至少超过1维)

使用
stack
将两个数据帧重塑为长格式,然后使用
unstack
执行合并和重塑,返回宽格式。有一系列重命名,这样我们就可以在合并中引用和对齐列

(df.rename_axis(index='instances', columns='cols').stack().to_frame('classes')
   .merge(parameters.rename_axis(columns='cols').stack().rename('vals'),
          on=['instances', 'classes', 'cols'])
   .unstack(-1)['vals']
   .rename_axis(index=None, columns=None)
)


非常感谢您详尽的回答!
       a     b     c     d
0   1639  1460   467  1239
1   1124   872   806   344
2   1083   511  1706  1500
3    958  1155  1268   563
4     14   242   777  1370
..   ...   ...   ...   ...
95  1435  1316  1709   755
96   346   712   363   815
97  1234   985   683  1348
98   127  1130  1009  1014
99  1370   825  1025  1855