【问题标题】:How to eliminate specific rows from an array?如何从数组中消除特定行?
【发布时间】:2019-02-26 16:08:44
【问题描述】:

我正在开发一种分析天气数据的工具。此时,所有数据都加载到一个名为master_array 的n×10 矩阵中,其中包含float64 数据类型的数据。我构建了一些过滤器,允许用户指定应该用于进一步计算的年份和月份。这些过滤器生成列表,例如。 G。一个包含整数的列表,如 2008 年至 2010 年期间的 years=[2008, 2009, 2010] 或另一个列表 months=[8, 9, 10] 8 月至 10 月。 master_array 的最后一列包含收集数据的年份、月份之前的列等等。

我现在努力的是构建一个函数,检查master_array 的最后一列是否与列表years 的元素匹配,并从master_array 中删除所有没有匹配项。 如果列表years 为空,则所有可用数据暂时应保存在master_array 中。

下一步基本相同,但使用master_array 中最后一列之前的列,当然使用列表months 而不是years

我不能保证master_array 中的值已排序,但该函数必须过滤矩阵。

我很确定我必须使用 numpys delete() 和 argwhere() 但我愿意接受任何有助于解决此问题的简单而整洁的解决方案。

提前致谢。

编辑:
对我来说,非常重要的是保留 master_array 或至少是它的副本并删除不再需要的行,而不是使用 vstack 或类似的东西创建新数组。

【问题讨论】:

  • 您可能需要考虑将Pandas 用于此类事情,因为它具有选择和切片时间索引数据(除其他外)的大量功能。无论如何,要继续使用您的方法,我认为您应该能够使用 np.isin 为您的过滤器制作选择蒙版。
  • @jdehesa 你能否提供更多关于 pandas 的详细信息,例如,当我没时间完成这个项目时,我应该关注哪些功能?
  • 好吧,如果您从未使用过 Pandas 并且您没有太多时间,您现在可能需要评估它是否值得,但如果您打算在 Python 中处理数据未来,Pandas 几乎是不可或缺的。周围有很多教程和资源,对于您的情况,您可以查看 this 的示例。
  • 例如,如果您有一个数据框df,索引为日期时间,您可以执行df[(df.year >= 2008) & (df.year <= 2010) & (df.month >= 8) & (df.month <= 10)] 之类的操作。

标签: python python-3.x numpy matrix


【解决方案1】:

您可以使用带有np.isin 的掩码,然后将数组替换为带有掩码的数组。 这是 numpy 推荐的方法

通常最好使用布尔掩码。例如:

mask = np.ones(len(arr), dtype=bool) mask[[0,2,4]] = 假结果 = arr[掩码,...]

等同于np.delete(arr, [0,2,4], axis=0),但允许进一步 使用mask

例子:

import numpy as np

#step 1: create an array with values and years (for illustration)
values = np.random.random(10)
years = np.array([2001, 2002, 2002, 2003, 2001,
                  2004, 2005, 2001, 2009, 2008])
master = np.vstack((values, years)).T
print(master[:,1])   # this will print master second column, i.e. years
>> ([2001, 2002, 2002, 2003, 2001, 2004, 2005, 2001, 2009, 2008])

# step 2: specify what years I want, then filter using a mask
filt_years = [2001, 2002]
mask = np.isin(master[:,1], filt_years)
print(mask)   #False values will be deleted
>> [ True  True  True False  True False False  True False False]

#step 3: apply mask and replace master (easier than deleting)
master = master[mask]
# or if you want to use delete:
master = np.delete(master, np.arange(len(master))[~mask], axis=0)

结合年份和月份并使用logical_and 的示例(即月份和年份都必须在选定的集合中):

months = np.array([1,1,2,2,1,4,5,8,9,5])
master = np.vstack((values, months, years)).T
filt_years = [2001, 2002]
filt_months = [1,2]
mask = np.logical_and(np.isin(master[:,2], filt_years), np.isin(master[:,1], filt_months))
master = master[mask]

【讨论】:

  • 老实说,您的回答包含许多我不熟悉或根本不理解的方面。首先:数组末尾的“.T”是什么?你明白了吗,我的矩阵已经包含了年和月,大部分这些值都是多次的?除此之外,我正在寻找一种从现有数组中删除不必要行而不是创建新行的方法。
  • 我添加了解释并扩展了代码,使其更“一步一步”。回答您的问题: 1) .T 表示转置:当我使用 vstack 时,我正在创建一个包含一行年份、一行值等的数组。使用.T,行变成列,所以master[:,1](第一个示例)是年份...请注意,我创建数据只是为了说明示例2)使用array = array[mask]比使用np.delete更容易,事实上推荐(见编辑)。您不是在创建新数组,而是用其中的一部分替换旧数组。
【解决方案2】:

感谢大家的建议。我终于在不使用 numpy 的 delete() 和 argwhere() 的组合的情况下解决了我的问题。起初我使用熊猫,但后来我意识到没有必要。 简而言之,我使用列表 monthsyears 的补充(当然,这需要知道数据集的最大时间段是多少[参见例如下面示例中的列表 all_years] ,没问题,因为它全部包含在我的master_array) 中,并且我可以实现从master_array 中排除与过滤器不匹配的每一行的补充,最后正是我想要的!

给你一个最终代码的例子:

for i in [x for x in all_years if x not in years]: #list containing the complement to the years chosen by user as filter
    master_arrayFilter = master_arrayFilter[master_arrayFilter[:,9] != i]

请注意,我在前一行中创建了一个名为 master_arrayFiltermaster_array 的“副本”。

这两条线完成这项工作仍然令人惊讶! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2019-12-12
    相关资源
    最近更新 更多