我有两个以下格式的数据文件:
File1中:
date,time,data1,data2,data3
date,time,data1,data2,data3
date,time,data1,data2,data3
文件2:
date,time,data4
date,time,data4
我想要做的是合并这两个文件中的行,如果日期和时间匹配,那么输出应该是:
date,time,data1,data2,data3,data4
如果一个文件中的时间戳与另一个文件中的任何内容都不匹配,那么我可以忽略该行。
我目前正在使用awk和join的组合。但我想知道这是否是最有效的方法。
目前的工作实施是这样的:
awk 'FS="," {print $1"&"$2 ","$3","$4","$5}' File1 > temp1
awk 'FS="," {print $1"&"$2 ","$3}' File2 > temp2
join -t',' -j1 1 -o 1.1,1.2,1.3,2.2,2.3 temp1 temp2 > temp3
awk 'FS="&" {print $1","$2"}' temp3 > Output
答案 0 :(得分:1)
我这样做的方式(假设日期和时间具有精确匹配格式)将是:
proc tidyUpTimestamp {date time} {
# If you want to parse/tidy up the timestamp, do so here
return $date,$time
}
# Schlurp the data into an array for ease of access. Good for a few million lines
set f [open "file2.csv"]
foreach line [split [read $f] "\n"] {
lassign [split $line ","] date time data4
set map([tidyUpTimestamp $date $time]) $data4
}
close $f
# Assuming that file1.csv is much longer than file2.csv
set fin [open "file1.csv"]
set fout [open "file1.processed.csv" w]
while {[gets $fin line] >= 0} {
lassign [split $line ","] date time; # Ignore other fields...
set ts [tidyUpTimestamp $date $time]
if {[info exist map($ts)]} {
# Simple concatenation!
puts $fout "$line,$map($ts)"
}
}
close $fout
close $fin
如果日期和时间不完全相同,则需要进行一些清理,因为上述代码完全依赖于所有内容的 textual 表示。只需将其弹出到tidyUpTimestamp
程序......
答案 1 :(得分:1)
假设这些文件没有重复date,time
我会cat
他们在一起,sort
和awk
如果当前行具有相同的date,time
{ {1}}如前一个那样打印上一行并从当前行追加数据:
cat file1.txt file2.txt | \
sort | \
awk '
function getOnlyData()
{
onlyData="";
for (i=3;i<=NF;i++)
{
onlyData = onlyData "," $i;
}
return onlyData
}
BEGIN {
FS=",";
}
{
if (prevDate==$1 && prevTime==$2)
{
currData = getOnlyData()
print $1 "," $2 prevData currData
}
prevDate=$1;
prevTime=$2;
prevData=getOnlyData();
}'
输入:
2013-10-07,12:00:00,a1,b1,c1 2013-10-07,13:00:00,a2,b2,c2 2013-10-07,14:00:00,a3,b3,c3 2013-10-07,15:00:00,x4,y4,z4 2013-10-07,16:00:00,x5,y5,z5
和
2000-10-07,12:00:00,d1 2013-10-07,13:00:00,d2 2000-10-07,14:00:00,d3 2013-10-07,15:00:00,d4 2000-10-07,16:00:00,d5
输出是:
2013-10-07,13:00:00,a2,b2,c2,d2 2013-10-07,15:00:00,d4,x4,y4,z4
答案 2 :(得分:1)
操作数据的灵活而通用的方法是python pandas。值得一提的是,它确实是适合这项工作的工具。允许在选定的索引行或列上进行电子表格或数据库样式合并/连接/连接。
两个示例文件来说明它是如何工作的
$ cat File1
date0,time0,data01,data02,data03
date1,time1,data11,data12,data13
date2,time2,data21,data22,data23
date3,time3,data31,data32,data33
date4,time4,data41,data42,data43
date5,time5,data51,data52,data53
$ cat File2
date1,time1,data14
date4,time4,data44
date2,time2,data24
运行python。 。
重要的比特:
$ python
>>> from pandas import merge, read_csv
>>> f1=read_csv("File1",header=None)
>>> f2=read_csv("File2",header=None)
>>> merged = merge(f1, f2, how='inner', left_on=[0,1], right_on=[0,1])
>>> merged.to_csv("Out", na_rep=0, index=False, header=False)
>>> [Ctrl-D]
完成工作!
$ cat Out
date1,time1,data11,data12,data13,data14
date2,time2,data21,data22,data23,data24
date4,time4,data41,data42,data43,data44
非常干净,没有弄乱。我真的很喜欢bash / grep / sed / awk perl和python在结构中操作数据但正确的工作工具使工作变得更加容易,并且更有可能使用数据。
<强>故障:强>
<强> 1。 read_csv 沼泽标准(简单,朴素)&#39; read_csv(&#34; File1&#34;)&#39; 将第一行视为标题名称。所以我们使用&#39; header = None&#39;。
>>> f1=read_csv("File1")
>>> f1
date0 time0 data01 data02 data03
0 date1 time1 data11 data12 data13
1 date2 time2 data21 data22 data23
2 date3 time3 data31 data32 data33
3 date4 time4 data41 data42 data43
4 date5 time5 data51 data52 data53
>>> f1=read_csv("File1",header=None)
>>> f1
0 1 2 3 4
0 date0 time0 data01 data02 data03
1 date1 time1 data11 data12 data13
2 date2 time2 data21 data22 data23
3 date3 time3 data31 data32 data33
4 date4 time4 data41 data42 data43
5 date5 time5 data51 data52 data53
>>> f2=read_csv("File2",header=None)
pandas DataFrame&#39; describe()&#39; 为大表提供了有用的摘要。对于数字数据,您还可以获得总数,最大值,最小值,平均值,e.t.c。
>>> f1.describe()
0 1 2 3 4
count 6 6 6 6 6
unique 6 6 6 6 6
top date4 time3 data01 data12 data13
freq 1 1 1 1 1
<强> 2。合并强>
如何指定左/右/内/外合并样式sql join术语。 how =&#39; left&#39; 将第一个文件索引(日期+时间)作为输出并合并到第二个文件数据中。 how =&#39; right&#39; 将第二个文件索引作为输出并合并到第一个文件数据中。 how =&#39; inner&#39; 执行每个文件索引(日期+时间)之间的交集,因此只会获取两个文件中都有条目的数据。 how =&#39; outer&#39; 在每个文件索引(日期+时间)之间建立联合,以便写入所有数据,在两个文件中没有条目的数据都用&填充#39; NaN的&#39;值。
on / left_on / right_on index select 我们还可以使用&#39; on = [0,1]&#39; ,因为我们的输入文件具有相同的索引列(并且它们的名称与我们在文件中读取的0和1相同,其中&#39; header = None&#39;)。
>>> merged = merge(f1, f2, how='inner', left_on=[0,1], right_on=[0,1])
>>> merged
0 1 2_x 3 4 2_y
0 date1 time1 data11 data12 data13 data14
1 date2 time2 data21 data22 data23 data24
2 date4 time4 data41 data42 data43 data44
>>> mergedOut = merge(f1, f2, how='outer', left_on=[0,1], right_on=[0,1])
>>> mergedOut
0 1 2_x 3 4 2_y
0 date0 time0 data01 data02 data03 NaN
1 date1 time1 data11 data12 data13 data14
2 date2 time2 data21 data22 data23 data24
3 date3 time3 data31 data32 data33 NaN
4 date4 time4 data41 data42 data43 data44
5 date5 time5 data51 data52 data53 NaN
第3。 to_csv 我们使用&#39; index = False&#39;写出没有和索引或标题和&#39; header = False&#39;。查看输出的索引和标题写入&#34; Out2&#34;文件:
>>> merged.to_csv("Out2")
>>> merged.to_csv("Out", na_rep=0, index=False, header=False)
$ cat Out2
,0,1,2_x,3,4,2_y
0,date1,time1,data11,data12,data13,data14
1,date2,time2,data21,data22,data23,data24
2,date4,time4,data41,data42,data43,data44
$ cat Out
date1,time1,data11,data12,data13,data14
date2,time2,data21,data22,data23,data24
date4,time4,data41,data42,data43,data44
开始使用的文档:
pandas用于读写数据文件的IO工具: http://pandas.pydata.org/pandas-docs/stable/io.html
pandas DataFrame对象: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html 选择行/列/数据。操作部分或全部数据集。大量的东西。
pandas merge / join / concat http://pandas.pydata.org/pandas-docs/stable/merging.html
获取pandas并安装:http://pandas.pydata.org/getpandas.html
# download, unpack and:
sudo python setup.py install