【问题标题】:Python csv writer Combine two columns in single rowPython csv writer 在单行中组合两列
【发布时间】:2018-10-21 08:45:07
【问题描述】:

我正在尝试在 csv 文件的第一列中写入 img_id(单个值),在 csv 文件的其余列中写入图像特征数组(f_descriptor_T)。 我写了以下代码:

path=/home/dir
listing = os.listdir(path)    

for file in listing:
    path_img_ext = os.path.join(path, file) #combine filename and extension
    data_read = feature_io.ReadFromFile(path_img_ext) #read single features of single image in each iteration 

    base=os.path.basename(file) #Extract image_id from its name
    os.path.splitext(file)
    img_id = os.path.splitext(base)[0]

    f_descriptor = data_read[2] #Extract particular array, from multiple arrays of features 

    feature_flat=f_descriptor.flatten() #Make flat array

    f_descriptor_T = np.array(feature_flat).T #Transpose feature array to convert col data to row form. 

    with open("output_0.csv", "a") as f:
        writer = csv.writer(f)
        writer.writerow([img_id])
        writer.writerow(f_descriptor_T)

不幸的是,输出在第一行显示img_id,在第二行显示f_descriptor_T,每次循环迭代,如下图所示:Output

但我想将两者(变量和数组)组合在单行中。

注意:我尝试使用 zip 和 concatenate 将两者结合起来,但失败了。

所需的输出应该是这样的:Desired Output不需要打印列标题,只需要在单行中打印 img_id 和 f_descriptor_T 数组。

【问题讨论】:

  • 你的数组f_descriptor_T是一个三行数组。你想让它们在 one 行是什么意思?
  • 我不会使用csv.writer 来编写数组。尝试使用np.savetxt 编写数组。更好的是,研究它的代码,看看它是如何直接写入数组行的(没有csv 模块)。
  • @Dyz 它将特征向量转换为 ["[-0.00369344 -0.08348401 0.29953018 ... 0.38050437 0.01184894],并将 ... 保存在 csv 中,而不是整个 numpy 特征数组。
  • @hpaulj 我想将其保存为 csv 格式以供进一步处理,而且我有一个变量(id)和一个数组(特征),我想将它们组合起来。
  • 进一步处理?通过什么方式?保存后的 csv 应该是什么样子?

标签: python csv numpy


【解决方案1】:

根据您当前的代码,f_descriptor_T 出现在不同的行上,因为您在对其余数据的不同 writerow 调用中提供了 f_descriptor_T(对 writerow 的每次调用都会创建一个新行)。

请注意,writerow 函数将要插入的数据作为列表形式的单个参数。

如果您希望它们位于同一行,则需要在同一个调用中提供它们。要按照您在“所需输出”图像中显示的方式执行此操作,您需要为作者提供一个单一的平面列表。

由于您有两种不同的数据类型(img_id 是字符串,f_descriptor_T 包含数字),我建议通过创建一个包含您的 img_id 的数组来执行此操作,然后添加 f_descriptor_T 的内容给它。您需要将 f_descriptor_T 转换为普通的 Python 列表。对于转换,您可以使用list 函数。

这里有一组最小的示例来演示该行为。

你想像示例 4 那样做。它类似于示例 2,但包含一个如何将 numpy 数组转换为普通 List 的示例。

import csv
import numpy as np

#example 1
with open("output_different_rows.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow(['foo'])
    writer.writerow(['bar'])

#example 2
with open("output_same_row.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow(['foo'] + ['bar'])
#example 3
with open("output_same_row_with_array.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow([['foo', 'bar'], 'too'])

#example 4
numpy_array = np.arange(0,9)
listified_array = list(numpy_array)
with open("output_same_row_numpy.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerow(['foo'] + listified_array)

【讨论】:

  • writer.writerow([[img_id], f_descriptor_T]),如果写了这一行,但 f_descriptor_T 损失仍然是值并显示 ... 像这样 ["[-0.1960862 -0.27065492 0.4554646 ... 0.07876456 -0.01247655]。我有两个值,img_id 和 f_descriptor_T,但您的示例包含 3 个值 foo、bar 和 too
  • 啊,当然,因为您使用的是 numpy 样式的数组,所以它不会打印逗号。在示例 3 中,我主要使用三个值来演示逗号的陷阱。 SFAIK,您需要编写自己的代码来解析 numpy 数组,从而将 f_descriptor_T 拆分回多个值。这有帮助吗?如果没有,您能否更具体地说明您缺少/需要澄清哪些信息?
  • (提供所需输出格式的具体示例将有很大帮助)
  • 我只想在单行打印img_id和f_descriptor_T,没有别的。
  • 信息不足。有多种输出格式可以这样描述,可能是无限的。请给我至少一行 CSV 文本,显示您想要的确切结果,并附上真实数据,然后我可以告诉您如何重现它。
【解决方案2】:

正在尝试重现您的 csv 文件

In [131]: arr = np.arange(10) # a flat array
In [132]: arr = np.array(arr).T
In [133]: arr
Out[133]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

我从一个平面文件开始,但仍然有一个平面文件(一维数组上的.T 什么都不做)

In [135]: with open('out.csv','a') as f:
     ...:     writer = csv.writer(f)
     ...:     writer.writerow(['id'])
     ...:     writer.writerow(arr.T)
     ...:     
In [136]: cat out.csv
id
0,1,2,3,4,5,6,7,8,9

顾名思义,每次调用writerow 都会写入一行。

但是使用savetxt,我可以轻松地在整齐的列和行中编写一个二维数组:

In [137]: np.savetxt('out.csv', arr.reshape(5,2), delimiter=',')
In [138]: cat out.csv
0.000000000000000000e+00,1.000000000000000000e+00
2.000000000000000000e+00,3.000000000000000000e+00
4.000000000000000000e+00,5.000000000000000000e+00
6.000000000000000000e+00,7.000000000000000000e+00
8.000000000000000000e+00,9.000000000000000000e+00
In [139]: np.savetxt('out.csv', arr.reshape(5,2), delimiter=',', fmt='%5d')
In [140]: cat out.csv
    0,    1
    2,    3
    4,    5
    6,    7
    8,    9

混合文本和数字有点棘手。

只需将两个变量放在列表中,我就可以将它们写入一行:

In [143]: with open('out.csv','w') as f:
     ...:     writer = csv.writer(f)
     ...:     writer.writerow(['id', arr])
     ...: 
     ...:     
In [144]: cat out.csv
id,[0 1 2 3 4 5 6 7 8 9]

实际上已经完成了:

f.writeline('%s,%s'%(id, arr))

也就是说,将列表格式化为字符串并写入。

【讨论】:

  • 但我希望在单行中输出。第二件事是,我已经转置数组,因为最初它存储在 col 中,所以我转置它以保存在 csv 行中。
  • 我还在猜测你真正想要什么。
  • 我只想在单行上显示 img_id(字符串)和 img_features(数组)。 f.writeline('%s,%s'%(id, arr)),它对 id 工作正常,但对 arr 不行。
猜你喜欢
  • 2014-10-02
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
相关资源
最近更新 更多