【问题标题】:Iterating over numpy array, np.ndindex making a mess迭代numpy数组,np.ndindex弄得一团糟
【发布时间】:2021-10-10 16:15:55
【问题描述】:

我有一个数据框,由于我必须对其执行许多计算,所以我想试试 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 吗?至少切片正确吗?

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

感谢任何建议!

【问题讨论】:

  • 这肯定感觉太复杂了。我并不完全清楚你想要做什么。你能举一个更简单的例子,一开始就没有np.emptydf.merge 业务吗?看起来你想要做的就是根据某些条件从现有列中计算一个新列——你不需要 NumPy。
  • @kwinkunks 最终我的目标是根据可用数据进行许多不同的时间敏感计算,但在这种情况下,我试图将数字附加到每一行的列内的列表中,并且出于某种原因,当我尝试这样做时,pandas 的行为不可预测,对于某些数字,它会附加 0,其中一些会将 + 添加到列表中,而另一些会根据需要附加
  • 好的,但是 pandasnumpy 与数据框、列表和数组的混合让我很难看到你想要做什么,无论如何对我来说。 Pandas 已经在内部使用 NumPy 来实现元素操作之类的东西——我真的不确定你需要在这里添加一个 NumPy 层。
  • np.ndindex(len(df2)) 并不比range(len(df2))

标签: python python-3.x numpy numpy-ndarray numpy-slicing


【解决方案1】:

您的数据框:

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     []

以及从它派生的数组(注意 object dtype):

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]

【讨论】:

  • 这个例子肯定会帮助我更好地理解这个主题!感谢您的努力,感谢您的帮助! p.s.(刚刚注意到我的情况...谢谢指出,菜鸟错误)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 2014-05-25
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 2020-01-07
  • 2011-06-18
相关资源
最近更新 更多