忽略第一列
数据格式示例:
Male, 110.90, 146.03 Male, 44.83, 211.82 … … Female, 78.67, 158.74 Male, 105.64, 164.21
忽略第一列:
with open("./weight_height_5.txt") as f: #determining number of columns from the first line of text n_cols = len(f.readline().split(",")) data = np.loadtxt("./weight_height_5.txt", delimiter=",",usecols=np.arange(1, n_cols)) print("First five rows:\n",data[:5])
指定文件路径
假设文件 “weight_height_1.txt”包含了体重和身高的数据。
110.90 146.03 44.83 211.82 97.13 209.30 105.64 164.21
我们的任务是读取文件并以我们可以在 NumPy 数组中表示的方式解析数据。
我们将导入 NumPy 包并调用 loadtxt 方法,将文件路径作为值传递给第一个参数 filePath。
import numpy as np data = np.loadtxt("./weight_height_1.txt")
该函数返回在文本中找到的 n 维 NumPy 值数组。
我们可以查看数据的“shape”和“dtype”属性
print("shape of data:",data.shape) print("datatype of data:",data.dtype)
加载 3D 数组
到目前为止,我们一直在以 2D NumPy 数组的形式读取文件的内容。
这是 np.loadtxt 方法的默认行为,我们无法指定另外的参数来将读取的数据解释为 3D 数组。
因此,解决这个问题的最简单方法是将数据作为 NumPy 数组读取,并使用 NumPy 的 reshape 方法将数据重塑为我们想要的任何维度的任何形状。
使用 NumPy reshape方法
我们希望数据被表示为一个 3D 数组。
我们可以通过使用 NumPy 的 reshape 方法简单地对返回的数据进行整形来实现这一点。
data = np.loadtxt("./weight_height_7.txt",delimiter=",") print("Current shape = ",data.shape) data = data.reshape(3,30,2) print("Modified shape = ",data.shape) print("fifth individual of section B - weight, height =",data[1,4,:])
指定数据类型
除非另有说明,NumPy 包的 np.loadtxt 函数默认假定传递的文本文件中的值是浮点值。
因此,如果我们传递的文本文件包含数字以外的字符,则该函数将抛出错误,指出它需要浮点值。
我们可以通过使用 datatype 参数指定文本文件中值的数据类型来解决这个问题。
数据格式示例:
13-2-1991 17-12-1990 18-12-1986
因此,我们将使用“-”作为分隔符来调用 loadtxt 方法:
data = np.loadtxt("./weight_height_4.txt", delimiter="-") print(data[:3]) print("datatype =",data.dtype)
如果我们查看上面几行代码的输出,我们会看到这三个值中的每一个都默认存储为浮点值,数组的数据类型为‘float64’。
我们可以通过将值“int”传递给“dtype”参数来改变这种行为。
这将要求函数将提取的值存储为整数,因此数组的数据类型也将为 int。
data = np.loadtxt("./weight_height_4.txt", delimiter="-", dtype="int") print(data[:3]) print("datatype =",data.dtype)
加载前 n 行
正如我们可以使用 skiprows 参数跳过前 n 行一样,我们也可以选择仅加载前 n 行并跳过其余行。
这可以使用 np.loadtxt 方法的 max_rows 参数来实现。
只读取文本文件“weight_height_2.txt”中的前十行:
data = np.loadtxt("./weight_height_2.txt", delimiter=",",max_rows = 10) print("Shape of data:",data.shape)
加载特定行
如果我们希望 np.loadtxt 函数只加载文本文件中的特定行,则没有参数支持此功能。
但是,我们可以通过定义一个生成器来实现这一点,该生成器接受行索引并返回这些索引处的行。
然后我们将这个生成器对象传递给我们的 np.loadtxt 方法。
让我们首先定义生成器:
def generate_specific_rows(filePath, row_indices=[]): with open(filePath) as f: # using enumerate to track line no. for i, line in enumerate(f): #if line no. is in the row index list, then return that line if i in row_indices: yield line
现在让我们使用 np.loadtxt 函数读取文件“weight_height_2.txt”中的第 2、4 和 100 行
gen = generate_specific_rows("./weight_height_2.txt",row_indices = [1, 3, 99]) data = np.loadtxt(gen, delimiter=",") print(data)
这应该返回一个具有三行两列的 NumPy 数组:
忽略标题
数据示例,CSV 文件“weight_height.csv”内容格式如下:
Weight (in Kg), height (in cm) 73.847017017515,241.893563180437 68.7819040458903,162.310472521300 74.1101053917849,212.7408555565
第一行是标题,我们可以使用下面方法忽略
data = np.loadtxt("./weight_height.csv", delimiter=",", skiprows=1) print(data[:3])
处理缺失值
正如我们在比较 np.loadtxt 与其他选项的部分中所讨论的, np.genfromtxt 默认处理缺失值。
我们没有任何直接的方法来处理 np.loadtxt 中的缺失值
在这里,我们将看看使用 np.loadtxt 方法处理缺失值的间接(和稍微复杂的)方法。
转换器参数:
- np.loadtxt 有一个 converters 参数,用于指定文件中每一列所需的预处理(如果有)。
- 例如,如果文本文件以厘米为单位存储高度列,而我们希望将它们存储为英寸,则可以为高度列定义一个转换器。
- 转换器参数接受一个字典,其中键是列索引,值是接受列值的方法,“转换”它并返回修改后的值。
我们如何使用转换器来处理缺失值?
- 我们需要首先确定默认数据类型,即用于填充实际值缺失位置的值。假设我们想用 0 填充缺失的高度和重量值,所以我们的 fill_value 将为 0。
- 接下来,我们可以为文件中的每一列定义一个转换器,它检查该列中是否有某个值或者空字符串,如果是空字符串,它将用我们的 fill_value 填充它。
- 为此,我们必须找到文本文件中的列数,我们已经在前面的部分中讨论了如何实现这一点。
使用 0 填充缺失值 。
# finding number of columns in the file with open("./weight_height_8.txt") as f: n_cols = len(f.readline().split(",")) print("Number of columns", n_cols) # defining converters for each of the column (using 'dictionary # comprehension') to fill each missing value with fill_value fill_value = 0 converters = {i: lambda s: float(s.strip() or fill_value) for i in range(2)} data = np.loadtxt("./weight_height_8.txt", delimiter=",",converters = converters) print("data shape =",data.shape) print("First 5 rows:\n",data[:5])
跳过最后一行
如果要排除文本文件的最后一行,可以通过多种方式实现。
我们可以定义另一个生成器,该生成器逐行生成并在最后一行之前停止,或者我们可以使用更简单的方法来计算文件中的行数,并将比该计数少的行数传递给 max_rows 参数.
计算行数:
with open("./weight_height_2.txt") as f: n = len(list(f)) print("n =", n)
现在 n 包含存在于 weight_height_2.txt
文件中的行数,该值应该是 100。
我们现在将像以前一样读取文本文件,使用 np.loadtxt 方法以及值为 n 1 的 max_rows 参数。
data = np.loadtxt("./weight_height_2.txt", delimiter=",",max_rows=n - 1) print("data shape =",data.shape)
np.loadtxt 通过指定选项(例如结果数组的数据类型、如何通过分隔符将一个数据条目与其他数据条目区分开、跳过/包括特定行等),为我们从文件读取数据的方式提供了很大的灵活性。
我们将在下面的教程中查看这些方法中的每a)
跳过特定列
假设我们想在从文本文件加载数据时通过指定这些列的索引来忽略某些列。
虽然 np.loadtxt 方法提供了一个参数来指定要保留的列(usecols),但它没有提供相反的方法,即指定要跳过的列。
让我们创建一个包装函数 loadtext_without_columns 来实现:
def loadtext_without_columns(filePath, skipcols=[], delimiter=","): with open(filePath) as f: n_cols = len(f.readline().split(delimiter)) #define a range from 0 to n_cols usecols = np.arange(0, n_cols) #remove the indices found in skipcols usecols = set(usecols) - set(skipcols) #sort the new indices in ascending order usecols = sorted(usecols) #load the file and retain indices found in usecols data = np.loadtxt(filePath, delimiter = delimiter, usecols = usecols) return data
测试数据格式示例:
110.90, 146.03, 3,7,1981 44.83, 211.82, 1,2,1986 97.13, 209.30, 14,2,1989 … … 105.64, 164.21, 3,6,2000
假设我们对个体的身高和出生日期不感兴趣,因此我们想跳过位置 1 和 2 的列。
data = loadtext_without_columns("./weight_height_6.txt",skipcols = [1, 2], delimiter = ",") # print first 5 rows print(data[:5])
指定分隔符
分隔符是一个字符或者一串字符串,用于分隔一行中的各个值。
在前面的文件中,分隔符是空格字符 (“”)。
指定逗号分隔符:
import numpy as np data = np.loadtxt("./weight_height_2.txt", delimiter = ",")
打印前5行来确认结果:
print("shape of array", data.shape) print("First 5 rows:\n", data[:5])
处理两个分隔符
np.loadtxt 方法中的 delimiter 参数只能传递一个值。
如果文件中有多个分隔符怎么办?
110.90, 146.03, 3-7-1981 44.83, 211.82, 1-2-1986 97.13, 209.30, 14-2-1989
解决方案:
# 首先从文件中读取每一行并将“-”替换为“,” with open("./weight_height_3.txt") as f_input: text = [l.replace("-", ",") for l in f_input] #calling the loadtxt method with “,“ as delimiter data = np.loadtxt(text, delimiter=",")
多个分隔符的一般方法
我们可以将分隔符解析设置成一个函数:
def generate_lines(filePath, delimiters=[]): with open(filePath) as f: for line in f: line = line.strip() #removes newline character from end for d in delimiters: line =line.replace(d, " ") yield line
使用方法:
gen = generate_lines("./weight_height_3.txt", ["-",","]) data = np.loadtxt(gen)