遍历 numpy 数组,np.ndindex 搞得一团糟

Iterating over numpy array, np.ndindex making a mess

我有一个数据框,因为我必须对其执行很多计算,所以我想我会尝试一下 Numpy,所以我只是在学习如何使用它。 这是我的数据框

df = pd.DataFrame({'col1': ['z', 'x', 'c', 'v', 'b', 'n'], 'col2': [100, 200, 300, 400, 500, 600]})
df1 = pd.DataFrame({'col1': ['z', 'x', 'c', 'v', 'b', 'n'], 'col2': [100, 212, 300, 405, 552, 641]})
df['col3'] = np.empty((len(df), 0)).tolist()
df1['col3'] = np.empty((len(df), 0)).tolist()

df2 = df.merge(df1, on='col1', how='outer')

现在我要做的是将 col2_y - col2_x - sum(col3_y) 追加到 col3_y如果 col2_y != col2_x。现在我试过了

df2 = df2.to_numpy()
    df = [df2[x, 3:4] - df2[x, 1:2] for x in np.ndindex(len(df2))]
    df2 = [np.where(df2[x, 1:2] != df2[x, 3:4],
                              np.append(df2[x, 4:5], (df2[x, 3:4] - df2[x, 1:2]) - (df2[x, 4:5].sum())),
                              df2[x, 4:5]) for x in np.ndindex(len(df2))]

但不知何故

[['z' 100 list([]) 100 list([])]
 ['x' 200 list([]) 212 list([])]
 ['c' 300 list([]) 300 list([])]
 ['v' 400 list([]) 405 list([])]
 ['b' 500 list([]) 552 list([])]
 ['n' 600 list([]) 641 list([])]]

变成这样

[array([[0]], dtype=object), 
 array([[12]],dtype=object),
 array([[0]],dtype=object),
 array([[5]], dtype=object), 
 array([[52]], dtype=object), 
 array([[41]], dtype=object)]

[array([[list([])]], dtype=object), 
 array([[list([])]], dtype=object), 
 array([[list([])]], dtype=object), 
 array([[list([])]], dtype=object), 
 array([[list([])]], dtype=object), 
 array([[list([])]], dtype=object)]

我没有正确使用 np.ndindex 吗?至少切片正确吗?

我什至需要它还是有更好的方法来完成我想做的事情?

我很感激任何建议!

你的数据框:

In [43]: df2
Out[43]: 
  col1  col2_x col3_x  col2_y col3_y
0    z     100     []     100     []
1    x     200     []     212     []
2    c     300     []     300     []
3    v     400     []     405     []
4    b     500     []     552     []
5    n     600     []     641     []

以及从中派生的数组(注意对象数据类型):

In [44]: arr = df2.to_numpy()
In [45]: arr
Out[45]: 
array([['z', 100, list([]), 100, list([])],
       ['x', 200, list([]), 212, list([])],
       ['c', 300, list([]), 300, list([])],
       ['v', 400, list([]), 405, list([])],
       ['b', 500, list([]), 552, list([])],
       ['n', 600, list([]), 641, list([])]], dtype=object)

那个迭代的区别——结果其实是一个列表:

In [46]: arr1 = [arr[x, 3:4] - arr[x, 1:2] for x in np.ndindex(len(arr))]
In [47]: arr1
Out[47]: 
[array([[0]], dtype=object),
 array([[12]], dtype=object),
 array([[0]], dtype=object),
 array([[5]], dtype=object),
 array([[52]], dtype=object),
 array([[41]], dtype=object)]

与系列相同的东西:

In [48]: df2['col2_y']-df2['col2_x']
Out[48]: 
0     0
1    12
2     0
3     5
4    52
5    41
dtype: int64

和数组列不同,没有迭代。对象 dtype 数学仍然比数字慢:

In [50]: arr[:,3]-arr[:,1]
Out[50]: array([0, 12, 0, 5, 52, 41], dtype=object)

一个 numpy 整数 dtype 版本:

In [51]: df2['col2_y'].to_numpy()-df2['col2_x'].to_numpy()
Out[51]: array([ 0, 12,  0,  5, 52, 41])

我不确定是否要处理以下行

[np.where(df2[x, 1:2] != df2[x, 3:4],
                              np.append(df2[x, 4:5], (df2[x, 3:4] - df2[x, 1:2]) - (df2[x, 4:5].sum())),
                              df2[x, 4:5]) for x in np.ndindex(len(df2))]

可以通过以下方式清理:

[np.where(x[1] != x[3],
          np.append(x[4], (x[3] - x[1]) - sum(x[4])),
          x[4]) 
 for x in arr]

由于所有 x[4] 列都是空列表,因此

[array([], dtype=float64),
 ...
 array([], dtype=float64)]

糟糕,我在某个地方摆弄了一些值到最后的列表:

In [65]: df2
Out[65]: 
  col1  col2_x col3_x  col2_y col3_y
0    z     100     []     100    [0]
1    x     200     []     212   [12]
2    c     300     []     300    [0]
3    v     400     []     405    [5]
4    b     500     []     552   [52]
5    n     600     []     641   [41]