如何修改CSV中的多个列,然后使用Ruby将它们复制到新的CSV?
在原始CSV中的10列中,我有4列需要生成整数(稍后使用MATLAB进行处理;其他6列已经包含整数值)。这四列分别是:(1)平台(2)推送(3)时间戳和(4)udid 示例输入为:如何修改CSV中的多个列,然后使用Ruby将它们复制到新的CSV?,ruby,csv,Ruby,Csv,在原始CSV中的10列中,我有4列需要生成整数(稍后使用MATLAB进行处理;其他6列已经包含整数值)。这四列分别是:(1)平台(2)推送(3)时间戳和(4)udid 示例输入为:#其他#列,Android,Y,10-05-2015 3:59:59 PM,#其他#列,d0155049772de9,#其他#列 相应的输出应该是:#其他#u列,2,1,1431273612198,#其他#u列,17923,#其他#u列 因此,我编写了以下代码: require 'csv' CSV.open('C:\
#其他#列,Android,Y,10-05-2015 3:59:59 PM,#其他#列,d0155049772de9,#其他#列
相应的输出应该是:#其他#u列,2,1,1431273612198,#其他#u列,17923,#其他#u列
因此,我编写了以下代码:
require 'csv'
CSV.open('C:\Users\hp1\Desktop\Datasets\NewColumns2.csv', "wb") do |csv|
CSV.foreach('C:\Users\hp1\Desktop\Datasets\NewColumns.csv', :headers=>true).map do |row|
if row['platform']=='Android'
row['platform']=2
elsif row['platform']=='iPhone'
row['platform']=1
end
if row['push']=='Y'
row['push']=1
elsif row['push']=='N'
row['push']=0
end
row['timestamp'].to_time.to_i
row['udid'].to_i
csv<<row
end
end
需要“csv”
CSV.open('C:\Users\hp1\Desktop\Datasets\NewColumns2.CSV',“wb”)do | CSV|
CSV.foreach('C:\Users\hp1\Desktop\Datasets\NewColumns.CSV',:headers=>true).映射do |行|
如果行['platform']=='Android'
行['platform']=2
elsif行['platform']=='iPhone'
行['platform']=1
结束
如果行['push']='Y'
行['push']=1
elsif行['push']=='N'
行['push']=0
结束
行['timestamp'].to_time.to_i
第['udid'行]至
csv这是地图的错误用法,这不是您需要的功能。如果要将函数应用于数组中的所有值,并返回数组,则需要映射。您所做的是迭代,进行一些更改,然后将修改后的行推送到一个新数组中-您可以只进行迭代,无需map函数:
CSV.foreach('C:\Users\hp1\Desktop\Datasets\NewColumns.CSV',:headers=>true)
而不是CSV.foreach('C:\Users\hp1\Desktop\Datasets\NewColumns.CSV',:headers=>true)。map
关于日期,您可以使用strtime将字符串转换为日期:DateTime.strtime(“10-05-2015 3:59:59 PM”,%d-%m-%Y%l:%m:%S%p”)
。这里的文档:将:converters=>:all
添加到您的选项中,以便自动转换日期和数字。然后,而不是
row['timestamp'].to_time.to_i
进行转换但不将其放置在任何位置(未放置到位),请执行以下操作:
row['timestamp'] = row['timestamp'].to_time.to_i
请注意,这只适用于转换器,否则行['timestamp']
是一个字符串,没有.to\u time
方法。编辑-重做,我遗漏了UDID的部分问题。
问题
当您不需要使用map时,CSV#foreach已经在所有行中进行了迭代-删除此项
日期-包括ruby标准时间库
唯一id-听起来好像您想将udid转换为较短的唯一id,因为每个移动设备可能有多个条目-使用数组创建集合而不重复,并使用数组中设备udid的索引作为新的较短的唯一id
我将此作为输入csv:
othercol1,platform,push,timestamp,othercol2,udid,othercol3,othercol4,othercol5,othercol6
11,Android, N, 10-05-2015 3:59:59 PM,22, d0155049772de9,33,44,55,66
11,iPhone, N, 10-05-2015 5:59:59 PM,22, d0155044772de9,33,44,55,66
11,iPhone, Y, 10-06-2015 3:59:59 PM,22, d0155049772de9,33,44,55,66
11,Android, Y, 11-05-2015 3:59:59 PM,22, d0155249772de9,33,44,55,66
这是我的输出csv:
11,2,0,1431298799,22,1,33,44,55,66
11,1,0,1431305999,22,2,33,44,55,66
11,1,1,1433977199,22,1,33,44,55,66
11,2,1,1431385199,22,3,33,44,55,66
以下是我使用的脚本:
require 'time' # use ruby standard time library to parse for you
require 'csv'
udids = [] # turn the udid in to a shorter unique id
CSV.open('new.csv', "wb") do |csv|
CSV.foreach('old.csv', headers: true) do |row|
if row['platform']=='Android'
row['platform']=2
elsif row['platform']=='iPhone'
row['platform']=1
end
if row['push'].strip =='Y'
row['push']=1
elsif row['push'].strip =='N'
row['push']=0
end
row['timestamp'] = Time.parse(row['timestamp']).to_i
# turn the udid in to a shorter unique id
unless udids.include?(row['udid'])
udids << row['udid']
end
row['udid'] = udids.index(row['udid']) + 1
csv << row
end
end
require'time'#使用ruby标准时间库为您解析
需要“csv”
udid=[]#将udid转换为较短的唯一id
CSV.open('new.CSV',“wb”)do | CSV|
CSV.foreach('old.CSV',headers:true)do |行|
如果行['platform']=='Android'
行['platform']=2
elsif行['platform']=='iPhone'
行['platform']=1
结束
如果行['push'].strip='Y'
行['push']=1
elsif行['push'].条带=='N'
行['push']=0
结束
行['timestamp']=Time.parse(行['timestamp'])。to_i
#将udid转入一个较短的唯一id
除非udid.include?(第['udid'行])
UDID欢迎使用堆栈溢出。需要示例输入数据。同时显示您的预期输出。另外,你能把你的代码减少到最低限度并且仍然显示出问题吗?谢谢。为了用裸最小代码表示问题,push列中有两种值-Y&N,我想将Y转换为1,N转换为0。但是这个代码不起作用:如果行['push']='Y'
行['push']=1
elsif行['push']='N'
行['push']=0
结束
和其他列也有类似的问题,我已经在问题细节中解释过了。我对Ruby很陌生,所以我意识到这可能是一个愚蠢的问题,也许解决方法很简单。不要在评论中解释,编辑你的问题,并将细节添加到问题中,就好像你最初把它们放在那里一样。在评论中加入细节会使问题更难解决。我们需要示例输入和您期望的结果。完成。还添加了示例输入和输出。感谢提供这些信息!但是当我尝试你的建议时,我得到了以下错误:“\u parse”中的:没有将nil隐式转换为字符串(TypeError)
。这用于时间戳
列;其他列将按原样复制,而不首先转换为整数。为什么?谢谢。我试过你的建议;我得到了以下错误:未定义nil的“to_time”方法:NilClass(NoMethodError)
。您能推荐一个解决方案吗?@user5346597一些时间戳列是空白的吗?如果是这样的话,您需要使用类似于row['timestamp']=row['timestamp'].to\u time.to\u i,除非row['timestamp'].nil?
好的,这就行了!但是,新csv不包含修改后的值。它包含与旧csv相同的值,这意味着它们根本没有被转换。如果你能解释一下,为什么会这样?此外,每一行现在包含两个附加列-它们包含0
和1
,所有行的顺序完全相同。