当前位置: 首页 > 面试题库 >

在Python中的多列上排序numpy数组

蓝飞
2023-03-14
问题内容

我正在尝试对column1,column2和column3的以下数组进行排序

[['2008' '1' '23' 'AAPL' 'Buy' '100']
 ['2008' '1' '30' 'AAPL' 'Sell' '100']
 ['2008' '1' '23' 'GOOG' 'Buy' '100']
 ['2008' '1' '30' 'GOOG' 'Sell' '100']
 ['2008' '9' '8' 'GOOG' 'Buy' '100']
 ['2008' '9' '15' 'GOOG' 'Sell' '100']
 ['2008' '5' '1' 'XOM' 'Buy' '100']
 ['2008' '5' '8' 'XOM' 'Sell' '100']]

我使用以下代码:

    idx=np.lexsort((order_array[:,2],order_array[:,1],order_array[:,0]))
    order_array=order_array[idx]

结果数组是

[['2008' '1' '23' 'AAPL' 'Buy' '100']
 ['2008' '1' '23' 'GOOG' 'Buy' '100']
 ['2008' '1' '30' 'AAPL' 'Sell' '100']
 ['2008' '1' '30' 'GOOG' 'Sell' '100']
 ['2008' '5' '1' 'XOM' 'Buy' '100']
 ['2008' '5' '8' 'XOM' 'Sell' '100']
 ['2008' '9' '15' 'GOOG' 'Sell' '100']
 ['2008' '9' '8' 'GOOG' 'Buy' '100']]

问题是最后两行是错误的。正确的数组应将最后一行作为倒数第二个。我已经尝试了所有方法,但无法理解为什么会这样。将不胜感激。

我正在使用以下代码来获取order_array。

 for i in ….
    x= ldt_timestamps[i] # this is a list of timestamps
    s_sym=……
    list=[int(x.year),int(x.month),int(x.day),s_sym,'Buy',100]   
    rows_list.append(list)

 order_array=np.array(rows_list)

问题答案:

tldr:在对数值数组进行数值计算时,NumPy会发光。尽管有可能(参见下文),但NumPy不太适合此操作。您最好使用Pandas。

问题原因:

这些值 将按字符串 排序。您需要将它们排序为ints

In [7]: sorted(['15', '8'])
Out[7]: ['15', '8']

In [8]: sorted([15, 8])
Out[8]: [8, 15]

发生这种情况是因为order_array包含字符串。您需要将这些字符串转换为ints适当的位置。

将dtype从string-dtype转换为数字dtype需要为新数组分配空间。因此,order_array从一开始就修改创建方式可能会更好。

有趣的是,即使您将值转换为整数,当您调用

order_array = np.array(rows_list)

默认情况下,NumPy创建一个 同质
数组。在齐次数组中,每个值都具有相同的dtype。因此,NumPy尝试在所有值中找到公分母,并选择了字符串dtype,从而阻碍了您将字符串转换为int的工作!

您可以通过检查order_array.dtype以下内容来自己检查dtype :

In [42]: order_array = np.array(rows_list)

In [43]: order_array.dtype
Out[43]: dtype('|S4')

现在,我们如何解决这个问题?

使用对象dtype:

最简单的方法是使用’object’dtype

In [53]: order_array = np.array(rows_list, dtype='object')

In [54]: order_array
Out[54]: 
array([[2008, 1, 23, AAPL, Buy, 100],
       [2008, 1, 30, AAPL, Sell, 100],
       [2008, 1, 23, GOOG, Buy, 100],
       [2008, 1, 30, GOOG, Sell, 100],
       [2008, 9, 8, GOOG, Buy, 100],
       [2008, 9, 15, GOOG, Sell, 100],
       [2008, 5, 1, XOM, Buy, 100],
       [2008, 5, 8, XOM, Sell, 100]], dtype=object)

这里的问题是,np.lexsort还是np.sort不要在D型的阵列工作object。为了解决这个问题,您可以rows_list
在创建之前对进行排序order_list

In [59]: import operator

In [60]: rows_list.sort(key=operator.itemgetter(0,1,2))
Out[60]: 
[(2008, 1, 23, 'AAPL', 'Buy', 100),
 (2008, 1, 23, 'GOOG', 'Buy', 100),
 (2008, 1, 30, 'AAPL', 'Sell', 100),
 (2008, 1, 30, 'GOOG', 'Sell', 100),
 (2008, 5, 1, 'XOM', 'Buy', 100),
 (2008, 5, 8, 'XOM', 'Sell', 100),
 (2008, 9, 8, 'GOOG', 'Buy', 100),
 (2008, 9, 15, 'GOOG', 'Sell', 100)]

order_array = np.array(rows_list, dtype='object')

更好的选择是将前三列合并为datetime.date对象:

import operator
import datetime as DT

for i in ...:
    seq = [DT.date(int(x.year), int(x.month), int(x.day)) ,s_sym, 'Buy', 100]   
    rows_list.append(seq)
rows_list.sort(key=operator.itemgetter(0,1,2))        
order_array = np.array(rows_list, dtype='object')

In [72]: order_array
Out[72]: 
array([[2008-01-23, AAPL, Buy, 100],
       [2008-01-30, AAPL, Sell, 100],
       [2008-01-23, GOOG, Buy, 100],
       [2008-01-30, GOOG, Sell, 100],
       [2008-09-08, GOOG, Buy, 100],
       [2008-09-15, GOOG, Sell, 100],
       [2008-05-01, XOM, Buy, 100],
       [2008-05-08, XOM, Sell, 100]], dtype=object)

即使这很简单,我也不喜欢dtype对象的NumPy数组。使用本地dtypes不会获得NumPy阵列的速度或节省内存空间的收益。在这一点上,您可能会发现使用Python列表列表更快,语法上更容易处理。

使用结构化数组:

仍然具有速度和内存优势的NumPy-
ish解决方案是使用结构化数组(而不是同类数组)。要使用结构化数组,np.array您需要显式提供dtype:

dt = [('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'),
      ('action', '|S4'), ('value', '<i4')]
order_array = np.array(rows_list, dtype=dt)

In [47]: order_array.dtype
Out[47]: dtype([('year', '<i4'), ('month', '<i4'), ('day', '<i4'), ('symbol', '|S8'), ('action', '|S4'), ('value', '<i4')])

要对结构化数组进行排序,可以使用以下sort方法:

order_array.sort(order=['year', 'month', 'day'])

要使用结构化数组,您需要了解同构数组和结构化数组之间的一些区别:

您最初的同质阵列是二维的。相反,所有结构化数组都是一维的:

In [51]: order_array.shape
Out[51]: (8,)

如果使用int索引结构化数组或遍历该数组,则会返回以下行:

In [52]: order_array[3]
Out[52]: (2008, 1, 30, 'GOOG', 'Sell', 100)

对于同构数组,您可以使用order_array[:, i]
Now来访问列,对于结构化数组,可以按名称访问它们:例如order_array['year']

或者,使用熊猫:

如果您可以安装Pandas,那么我认为使用Pandas DataFrame可能是最快乐的事情:

In [73]: df = pd.DataFrame(rows_list, columns=['date', 'symbol', 'action', 'value'])
In [75]: df.sort(['date'])
Out[75]: 
         date symbol action  value
0  2008-01-23   AAPL    Buy    100
2  2008-01-23   GOOG    Buy    100
1  2008-01-30   AAPL   Sell    100
3  2008-01-30   GOOG   Sell    100
6  2008-05-01    XOM    Buy    100
7  2008-05-08    XOM   Sell    100
4  2008-09-08   GOOG    Buy    100
5  2008-09-15   GOOG   Sell    100

熊猫具有有用的功能,可以按日期对齐时间序列,填充缺失值,分组和汇总/转换行或列。

通常,使用一个日期列而不是用于年,月,日的三个整数值的列更为有用。

如果您需要年,月,日作为单独的列以便输出,例如csv,则可以将日期列替换为年,月,日列,如下所示:

In [33]: df = df.html" target="_blank">join(df['date'].apply(lambda x: pd.Series([x.year, x.month, x.day], index=['year', 'month', 'day'])))

In [34]: del df['date']

In [35]: df
Out[35]: 
  symbol action  value  year  month  day
0   AAPL    Buy    100  2008      1   23
1   GOOG    Buy    100  2008      1   23
2   AAPL   Sell    100  2008      1   30
3   GOOG   Sell    100  2008      1   30
4    XOM    Buy    100  2008      5    1
5    XOM   Sell    100  2008      5    8
6   GOOG    Buy    100  2008      9    8
7   GOOG   Sell    100  2008      9   15

或者,如果您没有用“ date”列作为开始,那么您当然可以rows_list不理会,并从开始就用年,月,日列来构建DataFrame。排序仍然很容易:

df.sort(['year', 'month', 'day'])


 类似资料:
  • 问题内容: 如何按第n列对NumPy中的数组排序? 例如, 我想按第二列对行进行排序,以便返回: 问题答案: 对于“正确”的方式,请参见的关键字参数。 但是,你需要将数组视为具有字段的数组(结构化数组)。 如果你最初没有使用字段定义数组,那么“正确”的方法将非常丑陋。 作为一个简单的示例,对其进行排序并返回副本: 对其进行原位排序: 据我所知,确实是最优雅的方式… 此方法的唯一优点是,参数是用于排

  • 如何按第一列升序和第二列降序对NumPy中的2d数组进行排序? 例如 结果:

  • 问题内容: 我有一个多维数组。主数组是 我想做的是先对数组进行排序,然后再对进行排序。我知道在JavaScript 中您可以将自定义函数放入其中,就我而言,我有: 这是刚刚排序的一列,即OWNER_NAME很好,但我怎样修改它进行排序,然后? 问题答案: 如果所有者名称不同,请按它们排序。否则,使用决胜局的发布名称。

  • 问题内容: Python的复杂性是什么?Python是否检查给定的iterable是否已排序,还是我必须自己做?我在文档中的任何地方都找不到它。 问题答案: 这 完全 取决于实现。python保证的是内置排序算法是 稳定的 (比较相等的元素保留其相对顺序)。如果要实现,甚至可以使用稳定的冒泡排序。 Cpython使用TimSort(插入排序的合并排序合并),如果输入已经排序,我相信它具有O(N)的

  • 问题内容: 假设我有以下数组: 我怎么在那里我有值序列发生指数:?因此,在这种情况下的预期输出为:。 编辑: 1)请注意,这只是一个序列。可能是或或,仅此而已。 2)如果将我的数组修改为:,则具有相同序列的预期结果将是。 我正在寻找一些NumPy快捷方式。 问题答案: 嗯,这基本上是图像处理中经常出现的问题。这篇文章中列出了两种方法:基于纯NumPy和基于OpenCV(cv2)。 方法1: 使用N

  • 问题内容: 我不知道是否为此问题选择了合适的标题(如果没有,请相应地更改它),但是请考虑以下我正在使用的简化表结构: ,,,,,都是不相关的整数/浮筒,它们都代表不同的因素,并可以具有数量级的非常不同的顺序( 范围可从1 - 10,而的范围可以从100 - 1000 )。 我正在尝试选择条件相似的日期。给定一组,,,,,值我需要 返回由下令所有结果 接近 所有值作为一个整体 ,例如,如果,,,,和

  • 问题内容: 有没有办法将numpy 2D数组中的列顺序更改为新的任意顺序?例如,我有一个数组 我想将其更改为 通过应用排列 在列上。因此,在新矩阵中,我希望将原始文档的第一列保留在原位置,将第二列移至最后一列,依此类推。 有一个numpy函数可以做到吗?我有一个相当大的矩阵,并且希望得到更大的矩阵,因此我需要一个可以在可能的情况下快速且适当地执行此操作的解决方案(置换矩阵是不可行的) 谢谢。 问题

  • 问题内容: 我有一个numpy数组,其中特定行的每个单元格代表一个功能的值。我将它们全部存储在100 * 4矩阵中。 知道如何将每个值都介于0和1之间的numpy.array的行标准化吗? 我想要的输出是: 提前致谢 :) 问题答案: 如果我理解正确,那么您要做的就是除以每一列中的最大值。您可以使用广播轻松地做到这一点。 从示例数组开始: 在第0维(即行)上取最大值。这为您提供了一个大小向量,其中