【问题标题】:How to write an object typed array into csv file with NumPy?如何使用 NumPy 将对象类型数组写入 csv 文件?
【发布时间】:2022-06-22 18:10:59
【问题描述】:

我有两个要存储在 csv 文件中的 numpy 数组(A,B)和 2 个标量值(C,D)。 我知道如何在其中编写一个 numpy 数组:

A = np.array(...)
np.savetxt('path/to/file/filename.csv', A, delimiter = ",")

我希望我的 csv 文件的前两列包含 2 个数组 A 和 B,然后将 2 个标量值 C 和 D 作为第 3 列和第 4 列的第一个条目。

【问题讨论】:

    标签: python numpy csv


    【解决方案1】:

    由于 csv 文件是逗号分隔值,因此列的术语对 excel 文件更有用。如果我理解正确,您希望您的数据形状像这样

    A1 B1 C D 
    A2 B2  
    A3 B3
    .  .
    .  .
    .  .
    

    将数组更改为 pandas 数据框并保存您喜欢的任何内容(excel 或 csv)非常有用。如果我们回到您的问题,解决方案可能是这样的:

    A = np.array([1,2,3,4,5])
    B = np.array([5,4,3,2,1])
    C = [5]
    D = [6]
    
    
    _array = [A,B,C,D] #all values into list
    
    data = pd.DataFrame(_array).T  # in order to get what you want, you have to transpose dataframe
    
    data.to_csv('/Users/../data.csv',index=False,header=False)  # save as csv file
    
    data.to_excel('/Users/../data.xlsx',index=False,header=False) # save as excel file to get column based
    

    【讨论】:

      【解决方案2】:

      我认为您必须使用迭代或其他库,例如Pandas 这样做,因为每一列都有不同的大小(在本例中,我们将处理大小不等的 A 和 B) .因此,如果您想通过np.savetxt 执行此操作,则必须将保存的数组指定为 object 类型。如果你使用 object 类型的数组被 np.savetxt 保存,它只会填充 csv 文件的第一行:

      A = np.array([2, 4.1, 5], dtype=np.float64)
      B = np.array([2, 7, 9, 1], dtype=np.float64)
      C = 1
      D = 7
      
      Output = np.zeros((1, 4), dtype=object)
      Output[0, :] = A, B, C, D
      
      np.savetxt('Output.csv', Output, delimiter=",", fmt='%s')
      

      这将是:

      我不认为仅由 NumPy 就可以很好地处理它,最好尝试其他库,例如 Pandas 或……或使用迭代打开 csv 文件并导入它。但是,如果您想使用 NumPy 这样做(只是为了弄清楚如何通过 NumPy 完成这项工作),可以通过填充以间接方式均衡数组的大小来实现。为此,我们必须找到AB 的最大长度以将数组填充到该长度。在这个例子中,我用np.nan 填充了填充索引,然后removed it for the output

      max_len = max(A.shape[0], B.shape[0])
      
      A_pad = np.pad(A, (0, max_len - A.shape[0]), constant_values=(np.nan,))
      B_pad = np.pad(B, (0, max_len - B.shape[0]), constant_values=(np.nan,))
      C_pad = np.pad(np.array([C], dtype=np.float64), (0, max_len - 1), constant_values=(np.nan,))
      D_pad = np.pad(np.array([D], dtype=np.float64), (0, max_len - 1), constant_values=(np.nan,))
      
      Output = np.array([A_pad, B_pad, C_pad, D_pad]).T
      Output = Output.astype(str)
      Output[Output == 'nan'] = ''
      
      np.savetxt('Output.csv', Output, delimiter=",", fmt="%s")
      

      【讨论】:

      • 虽然我很欣赏这个解决方案,但将数组推入 pandas 更容易,并且默认情况下,根据 pandas 文档pandas.pydata.org/docs/reference/api/…,to_csv 会为您处理丢失的数据 repr.(nan values)。请检查我的解决方案。
      • @UtkuCan, (+1) 我提到 Pandas 和迭代会更容易使用。 但是,正如 OP 在问题标题中所写,它要求使用 NumPy。所以我通过 NumPy 展示了如何做到这一点。
      【解决方案3】:

      您需要先转换数组,可能使用zip_longest

      import csv
      from itertools import zip_longest
      import numpy as np
      
      A = np.array(...)  # 1d arrays
      B = np.array(...)
      C = 1.0  # scalars
      D = 2.0
      with open('filename.csv', 'w', newline='') as f:
          w = csv.writer(f)
          for row in zip_longest(A, B, [C], [D], fillvalue=''):
              w.writerow(row)
      

      如果 A 和 B 很长,每行的末尾会有很多空白单元格,可以修剪。

      【讨论】:

        【解决方案4】:

        我假设所有 A 和 B 的长度相同。我会使用 pandas 以我想要的方式组织它然后做pandas.DataFrame.to_csv() 我会这样做:

        import pandas as pd
        import numpy as np
        
        A = B = np.arange(5)  # 1d arrays
        C = 1.0  # scalars
        D = 2.0
        
        df = pd.DataFrame({'A': A, 'B': B, 'C': np.NaN, 'D': np.NaN})
        df.loc[0, 'C'] = C     # change 0 to 1 to fill the next row 
        df.loc[0, 'D'] = D     # change 0 to 1 to fill the next row
        df.to_csv('path/to/file/filename.csv')
        

        【讨论】:

          猜你喜欢
          • 2014-08-30
          • 1970-01-01
          • 2023-03-31
          • 2016-01-06
          • 2016-09-27
          • 2012-06-07
          • 2017-12-22
          • 2019-03-01
          • 2019-01-29
          相关资源
          最近更新 更多