【问题标题】:Deleting a row from an array从数组中删除一行
【发布时间】:2020-10-23 12:25:52
【问题描述】:

我正在处理一个名为 numbers 的数组,该数组将创建 4 列,分别称为 (x)、(y)、(z),第四列用于程序中。

我希望如果两行的 x y 值重合,那么根据它们的 c,其中一个将从主数组中删除(“0”z 值删除“1 ”,“1”z 值删除“2”,“2”z 值删除“0”)。

原始数组如下所示:

[[12 15  2  0]
 [65 23  0  0]
 [24 66  2  0]
 [65 23  1  0]
 [24 66  0  0]]

问题是当我尝试运行以下程序时,最后没有得到所需的数组。预期的输出数组如下所示:

[[12 15  2  0]
 [65 23  0  0]
 [24 66  2  0]]

我已经从下面的程序中摘录了一段

import numpy as np

#Array
numbers = np.array([[12,15,2,0],[65,23,0,0],[24,66,2,0],[65,23,1,0],[24,66,0,0]])

#Original Array
print(numbers)

#Lists to store x, y and z values
xs = []
ys = []
zs = []

#Any removed row is added into this list
removed = []

#Code to delete a row
for line1 in numbers:
    for line2 in numbers:
        if line1[0] == line2[0]:
            if line2[1] == line2[1]:
                if line1[2] == 1 and line2[2] == 0:    
                    removed.append(line1)
                if line1[2] == 0 and line2[2] == 2:    
                    removed.append(line1)
                if line1[2] == 2 and line2[2] == 1:    
                    removed.append(line1)

for i in removed:
    numbers = np.delete(numbers,i,axis=0)

for line in numbers:                        
    xs.append(line[0])
    ys.append(line[1])
    zs.append(line[2])

#Update the original Array
for i in removed:
    print(removed)

print()
print("x\n", xs)
print("y\n", ys)
print("z\n", zs)
print()
#Updated Array
print(numbers)

【问题讨论】:

  • 你会使用 Pandas 吗?
  • 这能回答你的问题吗? deleting rows in numpy array
  • 我曾考虑使用 pandas,但无法获得正确的代码构造。
  • 好吧,是也不是,因为我想确保我删除行的代码是准确的并且没有任何差异。
  • 如果三个 duplicate 行的 c 值分别为 0,1 和 2 - 哪个胜出?

标签: python arrays numpy-ndarray


【解决方案1】:

测试数组

a = lifeforms = np.array([[12,15,2,0],
                          [13,13,0,0],
                          [13,13,1,0],
                          [13,13,2,0],
                          [65,23,1,0],
                          [24,66,2,0],
                          [14,14,1,0],
                          [14,14,1,1],
                          [14,14,1,2],
                          [14,14,2,0],
                          [15,15,3,2],
                          [15,15,2,0],
                          [65,23,0,0],
                          [24,66,0,0]])

实现颜色选择的函数。

test_one = np.array([[0,1],[1,0],[1,2],[2,1]])
test_two = np.array([[0,2],[2,0]])

def f(g):
    a = g.loc[:,2].unique()
    if np.any(np.all(a == test_one, axis=1)):
        idx = (g[2] == g[2].min()).idxmax()
    elif np.any(np.all(a == test_two, axis=1)):
        idx = (g[2] == g[2].max()).idxmax()
    else:
        raise ValueError('group colors outside bounds')
    return idx

Groupby 前两列;迭代组;保存所需行的索引;使用这些索引从 DataFrame 中选择行。

df = pd.DataFrame(a)
gb = df.groupby([0,1])

indices = []
for k,g in gb:
    if g.loc[:,2].unique().shape[0] > 2:
        #print(f'(0,1,2) - dropping indices {g.index}')
        continue
    if g.shape[0] == 1:
        indices.extend(g.index.to_list())
        #print(f'unique - keeping index {g.index.values}')
        continue
    #print(g.loc[:,2])
    try:
        idx = f(g)
    except ValueError as e:
        print(sep)
        print(e)
        print(g)
        print(sep)
        continue 
    #print(f'keeping index {idx}')
    indices.append(idx)
    #print(sep)

print(df.loc[indices,:])

【讨论】:

    【解决方案2】:

    如果您可以使用 pandas,您可以执行以下操作:

    x = np.array([[12,15,2,0],[65,23,0,1],[24,66,2,0],[65,23,1,0],[24,66,0,0]])
    df = pd.DataFrame(x)
    new_df = df.iloc[df.loc[:,(0,1)].drop_duplicates().index]
    print(new_df)
    
        0   1  2  3
    0  12  15  2  0
    1  65  23  0  1
    2  24  66  2  0
    

    它的作用如下:

    1. 将数组转换为 pandas 数据帧
    2. df.loc[:,(0,1)].drop_duplicates().index 将返回您希望保留的行的索引(基于第一列和第二列)
    3. df.iloc 将返回切片的数据帧。

    根据 cmets 中的 OP 问题和@wwii 评论进行编辑:

    1. 您可以使用.to_numpy() 返回到numpy 数组,所以只需使用arr = new_df.to_numpy()

    2. 您可以尝试以下方法:

      xx = np.array([[12,15,2,0],[65,23,1,0],[24,66,2,0],[65,23,0,0],[24,66,0,0]])
      df = pd.DataFrame(xx)
      df_new = df.groupby([0,1], group_keys=False).apply(lambda x: x.loc[x[2].idxmin()])
      df_new.reset_index(drop=True, inplace=True)
      
          0   1  2  3
      0  12  15  2  0
      1  24  66  0  0
      2  65  23  0  0
      

    当需要考虑特殊的启发式时,可以执行以下操作:

    import pandas as pd
    import numpy as np
    
    def f_(x):
        vals = x[2].tolist()
        if len(vals)==2:
            # print(vals)
            if vals[0] == 0 and vals[1] == 1:
                return vals[0]
            elif vals[0] == 1 and vals[1] == 0:
                return vals[1]
            elif vals[0] == 1 and vals[1] == 2:
                return vals[0]
            elif vals[0] == 2 and vals[1] == 0:
                return vals[0]
        elif len(vals) > 2:
            return -1
        else:
            return x[2]
    
    xx = np.array([[12,15,2,0],[65,23,1,0],[24,66,2,0],[65,23,0,0],[24,66,0,0]])
    df = pd.DataFrame(xx)
    df_new = df.groupby([0,1], group_keys=False).apply(lambda x: x.loc[x[2] == f_(x)])
    df_new.reset_index(drop=True, inplace=True)
    print(df_new)
    
        0   1  2  3
    0  12  15  2  0
    1  24  66  2  0
    2  65  23  0  0
    

    【讨论】:

    • @wwii 来自示例输出,它看起来不像。看第二行
    • 我的错误 - 您的解决方案是否取决于行顺序? drop_duplicates 是否总是保留第一个?
    • @wwii in the docs:pandas.pydata.org/pandas-docs/version/0.17.1/generated/… 它说它保留第一个,但您可以在需要时更改它
    • @DavidS 代码是天才!!!它似乎解决了大部分问题,但我有几个问题。 1) 我可以将 new_df 转换为新的更新生命形式数组吗? 2) 你是如何指定要删除哪些颜色代码的?
    • 答案取决于原始数组的顺序,它不会尝试根据问题的 color 标准选择行。 np.array([[12,15,2,0],[65,23,1,0],[24,66,2,0],[65,23,0,0],[24,66,0,0]]) 失败
    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 2011-06-11
    • 2010-12-20
    相关资源
    最近更新 更多