【问题标题】:How to column stack arrays ignoring nan in Python?如何在Python中忽略nan的列堆栈数组?
【发布时间】:2015-07-12 22:14:21
【问题描述】:

我在文本文件中有表单的数据。

文本文件条目

#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 中完成?

【问题讨论】:

  • 如果您要处理数据分析,Pandas 将使生活更轻松,pd.read_table(file).dropna() 此处pd.read_table(file) 读取文件,dropna() 删除 NA 行。

标签: python arrays numpy pandas nan


【解决方案1】:

使用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]])

【讨论】:

    【解决方案2】:

    如果您阅读了 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
    

    【讨论】:

      【解决方案3】:

      您发现,库提供的功能并非总是易于使用。以下程序手动执行此操作,并使用数据文件中的值创建一个数组。

      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() 函数适用于列表,而不适用于数组 - 至少不适用于您使用的语法。扩展数组最简单的方法是“堆积”行,使用vstack(或hstack 用于列)

      2) 在genfromtxt() 中指定分隔符可能会咬你一口。默认情况下,分隔符是任何空白,这通常是您想要的。

      【讨论】:

        【解决方案4】:

        来自您的输入数据框:

        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
        

        【讨论】:

          猜你喜欢
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          • 2018-07-05
          • 2013-09-17
          • 2012-09-03
          • 2016-10-11
          • 1970-01-01
          相关资源
          最近更新 更多