在Python中对多个列上的numpy数组进行排序
我试图在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],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.
问题的原因: 值正在按字符串排序.您需要将它们排序为整数. In [7]: sorted(['15','8']) Out[7]: ['15','8'] In [8]: sorted([15,8]) Out[8]: [8,15] 发生这种情况是因为order_array包含字符串.您需要在适当的时候将这些字符串转换为int. 将dtypes从string-dtype转换为数字dtype需要为新数组分配空间.因此,您可能最好从一开始就修改创建order_array的方式. 有趣的是,即使您在调用时将值转换为整数 order_array = np.array(rows_list) NumPy默认创建一个同质数组.在同构数组中,每个值都具有相同的dtype.所以NumPy试图找到你所有人的共同点 您可以通过检查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,30,Sell,GOOG,9,8,15,5,XOM,100]],dtype=object) 这里的问题是np.lexsort或np.sort不适用于数组 In [59]: import operator In [60]: rows_list.sort(key=operator.itemgetter(0,2)) Out[60]: [(2008,'AAPL',100),(2008,'GOOG','Sell','XOM',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.day)),100] rows_list.append(seq) rows_list.sort(key=operator.itemgetter(0,2)) order_array = np.array(rows_list,dtype='object') In [72]: order_array Out[72]: array([[2008-01-23,[2008-01-30,[2008-01-23,[2008-09-08,[2008-09-15,[2008-05-01,[2008-05-08,dtype=object) 即使这很简单,我也不喜欢NypPy数组的dtype对象. 使用结构化数组: 更多NumPy-ish解决方案仍然提供速度和内存优势 dt = [('year','<i4'),('month',('day',('symbol','|S8'),('action','|S4'),('value','<i4')] order_array = np.array(rows_list,dtype=dt) In [47]: order_array.dtype Out[47]: dtype([('year','<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,100) 使用齐次数组,您可以使用order_array [:,i]访问列 或者,使用熊猫: 如果您可以安装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 Pandas具有按日期对齐时间序列,填补缺失的有用功能 通常,对于年,月,日而言,使用单个日期列而不是三个整数值列更有用. 如果您需要将年,日作为单独的列进行输出,比如说csv,那么您可以将日期列替换为年,日列,如下所示: In [33]: df = df.join(df['date'].apply(lambda x: pd.Series([x.year,x.month,x.day],index=['year','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 或者,如果您没有使用“日期”列开头,您当然可以单独留下rows_list,并从头开始构建包含年,日列的DataFrame.排序仍然很容易: df.sort(['year','day']) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |