在特定列中匹配索引值时联接numpy数组

2uluyalo  于 2023-05-29  发布在  其他
关注(0)|答案(2)|浏览(133)

我有多个numpy数组,每个数组有两列:一个包含测量,另一个包含该测量的年份。这些数组的长度和起点/终点都不同。我的目标是创建一个大型数组,其中包含一列,其中包含我拥有数据的整个时期的年份,以及许多列,其中包含来自每个输入数组的测量值。
基本上,我想写一个脚本,把这个:

import numpy as np

arr1 = np.array([[1920, 1921, 1922, 1924, 1925], [23, 54, 23, 54, 65]]).T
arr2 = np.array([[1922, 1923, 1924, 1925, 1926], [12, 43, 17, 42, 87]]).T

变成这样:

year  arr1  arr2
1920  23    nan
1921  54    nan
1922  23    12
1923  nan   43
1924  54    17
1925  65    42
1926  nan   87

我试着写一个if-else循环,检查两行的年份是否匹配,然后将测量值添加到输出数组中正确的行,但我似乎无法让它工作。我相信这是一个相当普遍的任务,所以我很抱歉,如果这个问题已经被问到之前,但我无法找到一个解决方案。
任何帮助都非常感谢!

bgibtngc

bgibtngc1#

看起来你不应该使用numpy,而应该使用pandas

import pandas as pd

df = (pd.DataFrame(arr1, columns=['year', 'arr1'])
        .merge(pd.DataFrame(arr2, columns=['year', 'arr2']),
               on='year', how='outer')
        .sort_values(by='year')
      )

输出:

year  arr1  arr2
0  1920  23.0   NaN
1  1921  54.0   NaN
2  1922  23.0  12.0
5  1923   NaN  43.0
3  1924  54.0  17.0
4  1925  65.0  42.0
6  1926   NaN  87.0
cnjp1d6j

cnjp1d6j2#

我想出这个答案主要是为了自己的学习。
下面是一个使用numpy.librecfunctions的例子。我对这个功能没有太多的经验。我不认为它被大量使用,尤其是现在更强大的panadas。但不管怎样。

In [14]: import numpy.lib.recfunctions as rf

使用相同的'idx'字段名,但不同的数据字段,从数组中创建结构化数组:

In [17]: rarr1=rf.unstructured_to_structured(arr1,names=['idx','col1'])
In [18]: rarr1
Out[18]: 
array([(1920, 23), (1921, 54), (1922, 23), (1924, 54), (1925, 65)],
      dtype=[('idx', '<i4'), ('col1', '<i4')])

In [19]: rarr2=rf.unstructured_to_structured(arr2, names=['idx','col1'])

使用join_by

In [22]: rjoint = rf.join_by('idx', rarr1, rarr2, 'outer')

In [23]: rjoint
Out[23]: 
masked_array(data=[(1920, 23, --), (1921, 54, --), (1922, 23, 12),
                   (1923, --, 43), (1924, 54, 17), (1925, 65, 42),
                   (1926, --, 87)],
             mask=[(False, False,  True), (False, False,  True),
                   (False, False, False), (False,  True, False),
                   (False, False, False), (False, False, False),
                   (False,  True, False)],
       fill_value=(999999, 999999, 999999),
            dtype=[('idx', '<i4'), ('col1', '<i4'), ('col2', '<i4')])

或不带掩码(99999是'nan'填充的'int'等效值)

In [27]: rjoint = rf.join_by('idx', rarr1, rarr2, 'outer',usemask=False)

In [28]: rjoint
Out[28]: 
array([(1920,     23, 999999), (1921,     54, 999999),
       (1922,     23,     12), (1923, 999999,     43),
       (1924,     54,     17), (1925,     65,     42),
       (1926, 999999,     87)],
      dtype=[('idx', '<i4'), ('col1', '<i4'), ('col2', '<i4')])

或者使用默认值(NAN不能很好地处理int值)

In [32]: rjoint = rf.join_by('idx', rarr1, rarr2, 'outer',usemask=False, defaults={'col1':-1, 'col2':-1})

In [33]: rjoint
Out[33]: 
array([(1920, 23, -1), (1921, 54, -1), (1922, 23, 12), (1923, -1, 43),
       (1924, 54, 17), (1925, 65, 42), (1926, -1, 87)],
      dtype=[('idx', '<i4'), ('col1', '<i4'), ('col2', '<i4')])

In [34]: rf.structured_to_unstructured(rjoint)
Out[34]: 
array([[1920,   23,   -1],
       [1921,   54,   -1],
       [1922,   23,   12],
       [1923,   -1,   43],
       [1924,   54,   17],
       [1925,   65,   42],
       [1926,   -1,   87]])

相关问题