首页 > 其他分享 >NumPy掩码数组(Masked Arrays)教程

NumPy掩码数组(Masked Arrays)教程

时间:2024-10-29 13:44:48浏览次数:8  
标签:dates plt Arrays china Masked 掩码 total 数据

简介

在处理数据时,我们经常会遇到缺失或无效的数据条目。如果想在不删除这些数据的情况下跳过或标记它们,可能需要使用条件语句或过滤数据。NumPy的numpy.ma模块提供了掩码数组(masked arrays)功能,可以更方便地处理这种情况。

掩码数组是标准NumPy ndarray和掩码(mask)的组合:

  • 数据部分是常规的numpy.ndarray,可以是任何形状或数据类型
  • 掩码是一个布尔数组,与数据形状相同
  • fill_value是一个可用于替换无效条目的值

掩码数组在以下情况下特别有用:

  1. 想保留被掩码的值以便后续处理,而不需要复制数组
  2. 需要处理多个带有各自掩码的数组
  3. 对缺失或无效值有不同的标记,希望保留这些标记而不是替换原始数据集中的值
  4. 无法避免或消除缺失值,但又不想在运算中处理NaN(Not a Number)值

此外,numpy.ma模块还提供了大多数NumPy通用函数(ufuncs)的特定实现,可以对掩码数据应用快速向量化函数和操作。

使用掩码数组分析COVID-19数据

我们将使用一个包含2020年初COVID-19疫情初期数据的CSV文件来演示掩码数组的使用。

首先导入所需的模块:

import numpy as np
import os
import matplotlib.pyplot as plt
from numpy import ma

读取数据

我们使用numpy.genfromtxt函数从CSV文件中读取数据:

filepath = os.getcwd()
filename = os.path.join(filepath, "who_covid_19_sit_rep_time_series.csv")

# 读取日期(第4-18列的第一行)
dates = np.genfromtxt(
    filename,
    dtype=np.str_,
    delimiter=",",
    max_rows=1,
    usecols=range(4, 18),
    encoding="utf-8-sig",
)

# 读取地理位置名称(跳过前6行,读取第1-2列)
locations = np.genfromtxt(
    filename,
    dtype=np.str_,
    delimiter=",",
    skip_header=6,
    usecols=(0, 1),
    encoding="utf-8-sig",
)

# 读取前14天的数值数据
nbcases = np.genfromtxt(
    filename,
    dtype=np.int_,
    delimiter=",",
    skip_header=6,
    usecols=range(4, 18),
    encoding="utf-8-sig",
)

数据探索

首先,我们可以绘制整个数据集的图表:

selected_dates = [0, 3, 11, 13]
plt.plot(dates, nbcases.T, "--")
plt.xticks(selected_dates, dates[selected_dates])
plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020")
plt.show()

从图表中可以看出,1月24日至2月1日期间的数据形状有些奇怪。我们需要进一步研究这些数据的来源。

处理中国数据

由于中国数据包含多个省份,我们需要将它们合并:

# 删除总计行
totals_row = 35
locations = np.delete(locations, (totals_row), axis=0)
nbcases = np.delete(nbcases, (totals_row), axis=0)

# 计算中国总数
china_total = nbcases[locations[:, 1] == "China"].sum(axis=0)
print(china_total)

输出结果中出现了负值,这显然是不正确的。问题在于数据中存在缺失值。

使用掩码数组处理缺失数据

我们可以使用掩码数组来正确处理缺失的数据:

nbcases_ma = ma.masked_values(nbcases, -1)

现在我们可以重新计算中国的总病例数:

china_masked = nbcases_ma[locations[:, 1] == "China"].sum(axis=0)
china_total = china_masked.data
print(china_total)

这次的结果没有负值了,但仍然存在一些问题:某些日期的累计病例数似乎在下降,这与"累计数据"的定义不符。

进一步细化中国数据

我们可以排除香港、台湾、澳门和"未指定"地区的数据,以获得更准确的中国大陆数据:

china_mask = (
    (locations[:, 1] == "China")
    & (locations[:, 0] != "Hong Kong")
    & (locations[:, 0] != "Taiwan")
    & (locations[:, 0] != "Macau")
    & (locations[:, 0] != "Unspecified*")
)

china_total = nbcases_ma[china_mask].sum(axis=0)

现在我们可以绘制更准确的中国大陆数据图表:

plt.plot(dates, china_total.T, "--")
plt.xticks(selected_dates, dates[selected_dates])
plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China")
plt.show()

数据拟合

为了估计缺失数据期间的病例数,我们可以使用简单的插值方法。首先,我们需要分离有效和无效的数据点:

invalid = china_total[china_total.mask]
valid = china_total[~china_total.mask]

# 获取有效数据对应的日期
valid_dates = dates[~china_total.mask]

然后,我们可以使用NumPy的多项式拟合功能创建一个三次多项式模型:

t = np.arange(len(china_total))
model = np.polynomial.Polynomial.fit(t[~china_total.mask], valid, deg=3)

最后,我们可以绘制一个包含实际数据和拟合曲线的图表,并估算出记录开始7天后(1月28日)的病例数:

plt.plot(t, china_total)
plt.plot(t[china_total.mask], model(t)[china_total.mask], "--", color="orange")
plt.plot(7, model(7), "r*")
plt.xticks([0, 7, 13], dates[[0, 7, 13]])
plt.yticks([0, model(7), 10000, 17500])
plt.legend(["Mainland China", "Cubic estimate", "7 days after start"])
plt.title(
    "COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China\n"
    "Cubic estimate for 7 days after start"
)
plt.show()

实际应用中的注意事项

  1. 使用numpy.genfromtxt函数时,将缺失数据替换为-1并不总是问题的最佳解决方案。在某些情况下,用0替换可能更合适,但这并非通用解决方案。

  2. numpy.genfromtxt函数有一个usemask参数。如果设置usemask=True,该函数会自动返回一个掩码数组,无需手动创建。

  3. 在处理真实数据时,通常需要仔细检查数据的特征和含义,以选择最合适的处理方法。掩码数组提供了一种灵活的方式来处理缺失或无效数据,同时保留原始数据的结构。

  4. 在进行数据分析和可视化时,掩码数组可以帮助我们更好地理解数据的质量和完整性。通过明确标记缺失或无效的数据点,我们可以避免在分析过程中引入偏差或错误。

  5. 当处理时间序列数据(如本例中的COVID-19数据)时,掩码数组特别有用。它们允许我们保留数据的时间结构,同时适当处理某些时间点的缺失数据。

  6. 在进行数据拟合或插值时,掩码数组可以帮助我们轻松地选择有效数据点进行计算,而无需修改原始数据结构。

  7. 对于大型数据集或需要频繁更新的数据,使用掩码数组可以提高代码的可维护性和可读性,因为它将数据处理逻辑与原始数据存储分离。

标签:dates,plt,Arrays,china,Masked,掩码,total,数据
From: https://blog.csdn.net/wuinb/article/details/143268997

相关文章

  • C. Concatenation of Arrays
    进行排序的运算符必须满足严格弱序(满足传递性和不可比性的传递性)按逆序对数排序显然不满足不可比性的传递性,如(1,5)(3,3)(2,6)同一个组内的两个数的相对大小不影响答案,应该猜想按较小值排序点击查看代码#include<bits/stdc++.h>usingnamespacestd;inta[100005][2];i......
  • Codeforces Round 980 (Div. 2) C. Concatenation of Arrays
    题目:给定n个数组a1,a2,…,an。每个数组的长度都是2。因此,ai=[ai,1,ai,2]。你需要将这些数组连接成一个长度为2n的单一数组,以便使结果数组中的逆序数最小。注意,你不需要实际计算逆序的数量。更正式地说,你需要选择一个长度为n的排列p,使得数组b=[ap1,1,ap1,2,......
  • 子网掩码划分的问题
    1ip地址分为网络位和主机位   总共32位     2   子网就是从主机地址借几位作为网络地址    假设子网为是x  则子网的个数是2的x次方,主机地址为y 则主机地址范围是2的y次方-2个2  题目  1.0.0.0/8的网络现在要求划分5个子网求......
  • 六,Arrays
    Arrays类详解Arrays类是Java标准库中提供的一个工具类,专门用于对数组进行各种操作。这个类提供了一系列静态方法,用于排序、搜索、比较数组以及将数组转换为字符串等。这些方法适用于所有对象数组和原始类型数组。Arrays类的特点工具类:Arrays类是一个工具类,只包含静态方......
  • 常用类:包装类,System类,Random类,Arrays
    包装类--integer相关包装inti1=Integer.parseInt("100");//String->intSystem.out.println(i1);Integeri2=Integer.valueOf("100");//String->IntegerSystem.out.println(i2);Integeri3=In......
  • Java数组工具类Arrays
    Arrays工具类将数组内容转为字符串对数组内容进行排序判断是否相同数组的复制查找特定值的索引用指定元素存满数组数组转列表Arrays工具类提供了一系列方便、高效的方法来操作和处理数组,大大简化了Java中对数组的常见操作。将数组内容转为字符串使用Arrays......
  • java.util.Arrays#sort
    基本数据类型数组/***java.util.Arrays#sort(int[])*publicstaticvoidsort(int[]a){*DualPivotQuicksort.sort(a,0,a.length-1,null,0,0);//DualPivotQuicksort*}*/Obje......
  • 深入解析网络通信的四大关键要素:网卡、MAC地址、IP地址、子网掩码与端口
    文章目录深入解析网络通信的四大关键要素:网卡、MAC地址、IP地址、子网掩码与端口**1.网卡(NetworkInterfaceCard,NIC)**关键知识点:联系与区别:**2.MAC地址(MediaAccessControlAddress)**关键知识点:联系与区别:**3.IP地址(InternetProtocolAddress)**关键知识......
  • Arrays常用API
    Arrays常用API本文主要总结了JAVA的Arrays工具类的常见使用方法,该工具类在机试刷题、面试过程中经常被问到,阅读完建议自己实践实践。1.常见API:1Arrays.toString()//输出数组的内容(基本数据类型)2Arrays.sort(arr);//排序,默认是升序3Arrays.binarySearch(int[]......
  • 彻底理解 IP 地址,子网掩码,子网划分
    彻底理解IP地址,子网掩码,子网划分 彻底理解IP地址,子网掩码,子网划分 原文地址:彻底理解IP地址,子网掩码,子网划分什么是IP协议在回答什么是IP协议前,我们先需要回答另外一个问题:什么是网络?从普通人的角度看,网络无非是手机上的一个WIFI标志,是电脑上一根网线而已。但......