如何在 Python 中忽略 nan 的列堆栈数组?
How to column stack arrays ignoring nan in Python?
我在文本文件中有表格的数据。
文本文件条目
#x y z
1 1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64 512
9 81 729
10 100 1000
11 121
12 144 1728
13 169
14 196
15 225
16 256 4096
17 289
18 324
19 361 6859
20 400
21 441 9261
22 484
23 529 12167
24 576
25 625
第三列中的一些条目是空的。我正在尝试创建一个忽略 nan 的 x(第 1 列)和 z(第 3 列)数组。设数组为B,B的内容应为:
1 1
8 512
9 729
10 1000
12 1728
16 4096
19 6859
21 9261
23 12167
我尝试使用以下代码执行此操作:
import numpy as np
A = np.genfromtxt('data.dat', comments='#', delimiter='\t')
B = []
for i in range(len(A)):
if ~ np.isnan(A[i, 2]):
B = np.append(B, np.column_stack((A[i, 0], A[i, 2])))
print B.shape
这不起作用。它创建一个列向量。如何在 Python 中完成?
如果您阅读 data.dat
文件并将内容分配给变量,请说 data
:
您可以遍历这些行并将它们拆分并仅处理具有 3 个元素的行:
B=[]
for line in data.split('\n'):
if len(line.split()) == 3:
x,y,z = line.split()
B.append((x,z)) # or B.append(str(x)+'\t'+str(z)+'\n')
# or any othr format you need
正如您发现的那样,库提供的功能并不总是易于使用。以下程序手动执行此操作,并使用数据文件中的值创建一个数组。
import numpy as np
def main():
B = np.empty([0, 2], dtype = int)
with open("data.dat") as inf:
for line in inf:
if line[0] == "#": continue
l = line.split()
if len(l) == 3:
l = [int(d) for d in l[1:]]
B = np.vstack((B, l))
print B.shape
print B
return 0
if __name__ == '__main__':
main()
注意:
1) append()
函数适用于列表,不适用于数组 - 至少不适用于您使用的语法。扩展数组的最简单方法是 'piling' 行,使用 vstack
(或 hstack
列)
2) 在 genfromtxt()
中指定分隔符可能会害了你。默认情况下,分隔符是任何白色 space,这通常是您想要的。
使用pandas
会让你的生活更轻松(注意定义delimiter
的正则表达式):
from pandas import read_csv
data = read_csv('data.dat', delimiter='\s+').values
print(data[~np.isnan(data[:, 2])][:, [0, 2]])
这导致:
array([[ 8.00000000e+00, 5.12000000e+02],
[ 9.00000000e+00, 7.29000000e+02],
[ 1.00000000e+01, 1.00000000e+03],
[ 1.20000000e+01, 1.72800000e+03],
[ 1.60000000e+01, 4.09600000e+03],
[ 1.90000000e+01, 6.85900000e+03],
[ 2.10000000e+01, 9.26100000e+03],
[ 2.30000000e+01, 1.21670000e+04]])
来自您的输入数据框:
In [33]: df.head()
Out[33]:
x y z
0 1 1 1
1 2 4 NaN
2 3 9 NaN
3 4 16 NaN
4 5 25 NaN
..你可以通过这样做得到输出数据帧B:
In [34]: df.dropna().head().drop('y', axis=1)
Out[34]:
x z
0 1 1
7 8 512
8 9 729
9 10 1000
11 12 1728
我在文本文件中有表格的数据。
文本文件条目
#x y z
1 1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64 512
9 81 729
10 100 1000
11 121
12 144 1728
13 169
14 196
15 225
16 256 4096
17 289
18 324
19 361 6859
20 400
21 441 9261
22 484
23 529 12167
24 576
25 625
第三列中的一些条目是空的。我正在尝试创建一个忽略 nan 的 x(第 1 列)和 z(第 3 列)数组。设数组为B,B的内容应为:
1 1
8 512
9 729
10 1000
12 1728
16 4096
19 6859
21 9261
23 12167
我尝试使用以下代码执行此操作:
import numpy as np
A = np.genfromtxt('data.dat', comments='#', delimiter='\t')
B = []
for i in range(len(A)):
if ~ np.isnan(A[i, 2]):
B = np.append(B, np.column_stack((A[i, 0], A[i, 2])))
print B.shape
这不起作用。它创建一个列向量。如何在 Python 中完成?
如果您阅读 data.dat
文件并将内容分配给变量,请说 data
:
您可以遍历这些行并将它们拆分并仅处理具有 3 个元素的行:
B=[]
for line in data.split('\n'):
if len(line.split()) == 3:
x,y,z = line.split()
B.append((x,z)) # or B.append(str(x)+'\t'+str(z)+'\n')
# or any othr format you need
正如您发现的那样,库提供的功能并不总是易于使用。以下程序手动执行此操作,并使用数据文件中的值创建一个数组。
import numpy as np
def main():
B = np.empty([0, 2], dtype = int)
with open("data.dat") as inf:
for line in inf:
if line[0] == "#": continue
l = line.split()
if len(l) == 3:
l = [int(d) for d in l[1:]]
B = np.vstack((B, l))
print B.shape
print B
return 0
if __name__ == '__main__':
main()
注意:
1) append()
函数适用于列表,不适用于数组 - 至少不适用于您使用的语法。扩展数组的最简单方法是 'piling' 行,使用 vstack
(或 hstack
列)
2) 在 genfromtxt()
中指定分隔符可能会害了你。默认情况下,分隔符是任何白色 space,这通常是您想要的。
使用pandas
会让你的生活更轻松(注意定义delimiter
的正则表达式):
from pandas import read_csv
data = read_csv('data.dat', delimiter='\s+').values
print(data[~np.isnan(data[:, 2])][:, [0, 2]])
这导致:
array([[ 8.00000000e+00, 5.12000000e+02],
[ 9.00000000e+00, 7.29000000e+02],
[ 1.00000000e+01, 1.00000000e+03],
[ 1.20000000e+01, 1.72800000e+03],
[ 1.60000000e+01, 4.09600000e+03],
[ 1.90000000e+01, 6.85900000e+03],
[ 2.10000000e+01, 9.26100000e+03],
[ 2.30000000e+01, 1.21670000e+04]])
来自您的输入数据框:
In [33]: df.head()
Out[33]:
x y z
0 1 1 1
1 2 4 NaN
2 3 9 NaN
3 4 16 NaN
4 5 25 NaN
..你可以通过这样做得到输出数据帧B:
In [34]: df.dropna().head().drop('y', axis=1)
Out[34]:
x z
0 1 1
7 8 512
8 9 729
9 10 1000
11 12 1728