【问题标题】:Restructure numpy array based on column and row list (Like pivot table in numpy array)基于列和行列表重构numpy数组(如numpy数组中的数据透视表)
【发布时间】:2022-01-09 20:03:23
【问题描述】:

这里是示例 numpy 数据源

     col    row1   row2   row3  row4  columns
[[(  11.2, '689', '197', 'value_2', 0, 1)]
 [(  56.4, '689', '197', 'value_3', 0, 1)]
 [(  195.7, '689', '197', 'value_2', 0, 2)]
 [(  565.2, '689', '197', 'value_3', 0, 2)]
 [(  227.6, '689', '197', 'value_2', 0, 3)]
 [(  1347.6, '689', '197', 'value_2', 0, 3)]
 [( 613.5, '689', '196', 'value_2', 0, 1)]
 [(139. , '689', '196', 'value_3', 0, 1)]
 [( 6011. , '689', '196', 'value_2', 0, 2)]
 [(103. , '689', '196', 'value_3', 0, 2)]
 [( 6860. , '689', '196', 'value_2', 0, 3)]
 [(1302. , '689', '196', 'value_3', 0, 3)]
 [( 1787.9, '622', '197', 'value_2', 0, 1)]
 [( 632.5, '622', '197', 'value_3', 0, 1)]
 [( 178.8, '622', '197', 'value_2', 0, 2)]
 [( 6360.5, '622', '197', 'value_3', 0, 2)]
 [( 228. , '622', '196', 'value_2', 0, 1)]
 [(672. , '622', '196', 'value_3', 0, 2)]
 ]

所以从这个预期的输出应该是

                                   1       2       3

row1   row2    row3        row4
689    197     value_2     0       11.2    195.7   227.6
689    197     value_3     0       56.4    565     1347
689    196     value_2     0       613.5   6011    6860
689    196     value_3     0       139     103     1302
622    197     value_2     0       1787    178     
622    197     value_3     0       632     6360

超过 1 2 3 列是从 numpy 数组中的一列得到的,即排名

从给定的数据来看,row1 永远是 1,但它有多个 row2、row3 和 row4。 对于 row1 中的每个数据,都应该找到等效的行并按照输出中的说明进行填充。

我尝试了下面的代码,但无法正确获取 (1, 2, 3) 列值,因为它位于不同的位置,我无法在 numpy 数组中写入。

new_temp_arr = 'actual_data_given'
m = 1
row_list = ['row1', 'row2', 'row3', 'row4']
# Column list taken from the array based on rank column
column_list = [1, 2, 3]
sample_list = []

for value in new_temp_arr:
    for new_value in new_temp_arr:
        if m >= len(new_temp_arr):
            break
        new_value = new_temp_arr[m]
        # Checking all the values for the rows matches with one another
        condition = [value[row] == new_value[row] for row in row_list]
        if all(condition):
            # Looping through all the column list and getting the float value
            # I'm stuck here, how to store the values with properly matched data
            for per in column_list:
                if new_value['rank'] == [per]:
                    float_value = new_value['float_value']
                    sample_list.append(new_value)
        m += 1

【问题讨论】:

  • “示例 numpy 数据源”的性质尚不清楚。列标题不是数组的一部分。 []() 的嵌套表明它是一个结构化数组,但您没有提供 shape 或 dtype。但它可能是对象 dtype,或者只是元组列表。我不认为numpy 在这里会有所帮助。对于分组操作,我喜欢使用dict,甚至collections.defaultdict
  • 是的,它是一个结构化数组,我提到的 dtype 为 col 行等。感谢您的输入,我尝试使用 defaultdict
  • 你知道完整的唯一row#值吗?
  • 唯一行,意思是,你到底在问什么?

标签: python numpy numpy-ndarray


【解决方案1】:

我认为您不能使用 numpy 有效地做到这一点,尤其是因为您的数据中有重复项并且简单的数据透视会失败(您似乎保留了第一个值,尽管不完全确定,请澄清这一点)。

此外,您的输出看起来像是一个数据框,那么为什么不直接将pandaspivot_tableaggfunc='first' 一起使用呢?:

a = np.array([[(  11.2, '689', '197', 'value_2', 0, 1)],
              [(  56.4, '689', '197', 'value_3', 0, 1)],
              [(  195.7, '689', '197', 'value_2', 0, 2)],
              [(  565.2, '689', '197', 'value_3', 0, 2)],
              [(  227.6, '689', '197', 'value_2', 0, 3)],
              [(  1347.6, '689', '197', 'value_2', 0, 3)],
              [( 613.5, '689', '196', 'value_2', 0, 1)],
              [(139. , '689', '196', 'value_3', 0, 1)],
              [( 6011. , '689', '196', 'value_2', 0, 2)],
              [(103. , '689', '196', 'value_3', 0, 2)],
              [( 6860. , '689', '196', 'value_2', 0, 3)],
              [(1302. , '689', '196', 'value_3', 0, 3)],
              [( 1787.9, '622', '197', 'value_2', 0, 1)],
              [( 632.5, '622', '197', 'value_3', 0, 1)],
              [( 178.8, '622', '197', 'value_2', 0, 2)],
              [( 6360.5, '622', '197', 'value_3', 0, 2)],
              [( 228. , '622', '196', 'value_2', 0, 1)],
              [(672. , '622', '196', 'value_3', 0, 2)],
             ])
cols = ['col', 'row1', 'row2', 'row3', 'row4', 'columns']
(pd.DataFrame(a[:,0,:], columns=cols)
   .pivot_table(index=['row1', 'row2', 'row3', 'row4'], columns='columns', values='col', aggfunc='first')
)

输出:

columns                      1       2       3
row1 row2 row3    row4                        
622  196  value_2 0      228.0     NaN     NaN
          value_3 0        NaN   672.0     NaN
     197  value_2 0     1787.9   178.8     NaN
          value_3 0      632.5  6360.5     NaN
689  196  value_2 0      613.5  6011.0  6860.0
          value_3 0      139.0   103.0  1302.0
     197  value_2 0       11.2   195.7   227.6
          value_3 0       56.4   565.2     NaN

如果订单很重要,您可以reindex原始订单:

cols = ['col', 'row1', 'row2', 'row3', 'row4', 'columns']
df = pd.DataFrame(a[:,0,:], columns=cols)

idx = df.set_index(['row1', 'row2', 'row3', 'row4']).index
idx = idx[~idx.duplicated(keep='first')]

(df.pivot_table(index=['row1', 'row2', 'row3', 'row4'], columns='columns', values='col', aggfunc='first')
   .reindex(idx)
)

输出:

columns                      1       2       3
row1 row2 row3    row4                        
689  197  value_2 0       11.2   195.7   227.6
          value_3 0       56.4   565.2     NaN
     196  value_2 0      613.5  6011.0  6860.0
          value_3 0      139.0   103.0  1302.0
622  197  value_2 0     1787.9   178.8     NaN
          value_3 0      632.5  6360.5     NaN
     196  value_2 0      228.0     NaN     NaN
          value_3 0        NaN   672.0     NaN

【讨论】:

  • 我必须只使用 numpy,这是要求。订单不是问题。任何值都可以排在第一位,这不是问题。我只需要用 numpy 提取这个结构。
【解决方案2】:
def get_list(arr, row1, row_column_values, row_list, column_list, index):
    dict_keys = {i: [] for i in column_list}
    dic = {row1: dict_keys}
    for value in arr:
        if index == len(arr):
            index = 0
        value = arr[index]
        condition = [value[row][0] == row_column_values[row] for row in row_list]
        if all(condition):
            dic[row1][int(value['rank'][0])] = value['float_value'][0]
            if index == 0:
                break
        index += 1
        
        
new_temp_arr = 'actual_data_given'
m = 1
row_list = ['row1', 'row2', 'row3', 'row4']
# Column list taken from the array based on rank column
column_list = [1, 2, 3]
out_array = np.zeros() #Numpy array with type
dic = {}
    
for value in new_temp_arr:
    row_values = {row: value[row][0] for row in row_list}
    dic = get_list(new_temp_arr, value['row1'][0], row_values, row_list, column_list, m)
    float_value = list(dic[value['row1'][0]].values())
    out_array[out_index] = tuple(list(value[row_list][0]) + float_value)

return out_array
 

上面的代码得到了我在问题中提到的预期结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-06
    • 2022-01-25
    • 1970-01-01
    • 2018-12-21
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多