想获取输入数据和源代码?点这里!
处理一:将数据中所有信息有问题的那行信息删除。如样例中第4行数据,这一行数据只有3个元素,而其他行都有6个元素,所以删除第4行即可。再如最后一行第3个信息明显有问题,所以该行也是问题行,删除即可。将全部数据处理完之后,每行单个元素以逗号为分隔,写入文件test1。
输入数据样例
18 Jogging 102271561469000 -13.53 16.89 -6.4
18 Jogging 102271641608000 -5.75 16.89 -0.46
18 Jogging 102271681617000 -2.18 16.32 11.07
18 Jogging 3.36
18 Downstairs 103260201636000 -4.44 7.06 1.95
18 Downstairs 103260241614000 -3.87 7.55 3.3
18 Downstairs 103260321693000 -4.06 8.08 4.79
18 Downstairs 103260365577000 -6.32 8.66 4.94
18 Downstairs 103260403083000 -5.37 11.22 3.06
18 Downstairs 103260443305000 -5.79 9.92 2.53
6 Walking 0 0 0 3.214402
输出test1样例
18,Jogging,102271561469000,-13.53,16.89,-6.4
18,Jogging,102271641608000,-5.75,16.89,-0.46
18,Jogging,102271681617000,-2.18,16.32,11.07
18,Downstairs,103260201636000,-4.44,7.06,1.95
18,Downstairs,103260241614000,-3.87,7.55,3.3
18,Downstairs,103260321693000,-4.06,8.08,4.79
18,Downstairs,103260365577000,-6.32,8.66,4.94
18,Downstairs,103260403083000,-5.37,11.22,3.06
18,Downstairs,103260443305000,-5.79,9.92,2.53
我的代码
#!/usr/bin/env python3
import csv
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
with open(input_file, 'r', newline='') as csv_in_file:
with open(output_file, 'w', newline='') as csv_out_file:
filereader = csv.reader(csv_in_file, delimiter=' ')
filewriter = csv.writer(csv_out_file)
for row_list in filereader:
if len(row_list) == 6 and row_list[2] != '0':
filewriter.writerow(row_list)
处理一是一个数据清洗的过程。输出文件的要求是“每行单个元素以逗号为分隔”,这不难让人想到要使用CSV逗号分隔值文件。首先对输入文件和输出文件进行打开操作,然后使用csv模块的reader()
和writer()
函数分别创建了两个对象filereader
和filewriter
。因为输入文件的每行的单个元素都以空格分隔,因此我们在创建对象filereader
的时候,需要把reader()
函数的delimiter
参数设置为delimiter=' '
,表示以空格作为分隔符。
我们来分析一下数据样本。样本中有问题的数据行有两种,一种类似于上面输入数据样例的第4行数据,缺少数据元素;另一种类似于输入数据样例的最后一行数据,第3列的数据元素为0。针对第一类问题,我们可以通过判断列表长度的方法将其筛掉,即判断len(row_list)
是否为6。而对于第二类问题,我们只需要判断row_list
列表中索引为2的元素是否为'0'
(注意这里的0是一个字符而并非一个数字)。对于满足条件的数据行,我们将其写入输出文件。
处理二:将test1数据中所有动作的数目统计出来,将动作数目打印到屏幕。然后将动作数目变为100的倍数,多余的删除,将数据行写入输出文件test2。比如统计出Jogging的数量为3021次,那么打印出3021后只往输出文件test2中写入3000条。
我的代码
#!/usr/bin/env python3
import csv
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
movementsDict = {}
inputData = []
with open(input_file, 'r', newline='') as csv_in_file:
filereader = csv.reader(csv_in_file)
movementsList = []
for row_list in filereader:
movementsList.append(row_list[1])
for movement in movementsList:
if movement not in movementsDict:
movementsDict[movement] = 1
else:
movementsDict[movement] += 1
for movement, movementsDict[movement] in movementsDict.items():
print('Movement: %-15s' % movement, end='')
print('Amount: ' + str(movementsDict[movement]))
movementsDict[movement] = movementsDict[movement] // 100 * 100
inputData.append(movementsDict[movement])
csv_in_file.seek(0, 0)
with open(output_file, 'w', newline='') as csv_out_file:
filewriter = csv.writer(csv_out_file)
countWalking = 0
countJogging = 0
countUpstairs = 0
countDownstairs = 0
countStanding = 0
countSitting = 0
for row_list in filereader:
if row_list[1] == 'Walking':
if countWalking < inputData[0]:
filewriter.writerow(row_list)
countWalking += 1
elif row_list[1] == 'Jogging':
if countJogging < inputData[1]:
filewriter.writerow(row_list)
countJogging += 1
elif row_list[1] == 'Upstairs':
if countUpstairs < inputData[2]:
filewriter.writerow(row_list)
countUpstairs += 1
elif row_list[1] == 'Downstairs':
if countDownstairs < inputData[3]:
filewriter.writerow(row_list)
countDownstairs += 1
elif row_list[1] == 'Standing':
if countStanding < inputData[4]:
filewriter.writerow(row_list)
countStanding += 1
else:
if countSitting < inputData[5]:
filewriter.writerow(row_list)
countSitting += 1
对于计数,我们可以应用Python的字典。这和我之前写过的统计文章中单次出现的次数的程序类似。首先建立一个空字典movementsDict
和一个空列表movementsList
。读取文件时,每个数据行是一个具有6个元素的列表,其中索引为1的元素就是我们要计数的动作。我们把索引为1的元素加入到movementsList
中,然后对其中的元素通过字典来计数。为了以100为精确度,我们进行movementsDict[movement] = movementsDict[movement] // 100 * 100
的运算。在写入输出文件的时候,我采用了每个动作分别计数的策略,每写入一行就令计数器+1。当计数器变量超过给定数值的时候,停止写入。
处理三:将test2中的数据读出,每行只取最后3列,每行数据中的单个元素以空格隔开,写入文件test3。
输出test3样例
-0.72 9.62 0.14982383
-4.02 11.03 3.445948
0.95 14.71 3.636633
我的代码
#!/usr/bin/env python3
import csv
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
my_columns = [3, 4, 5]
with open(input_file, 'r', newline='') as csv_in_file:
with open(output_file, 'w', newline='') as csv_out_file:
filereader = csv.reader(csv_in_file)
filewriter = csv.writer(csv_out_file, delimiter=' ')
for row_list in filereader:
row_list_output = []
for index_value in my_columns:
row_list_output.append(row_list[index_value])
filewriter.writerow(row_list_output)
处理三还是比较简单的。输出文件只要求保留最后三列,即列索引值为3, 4, 5的三列。我们创建一个列表变量my_columns = [3, 4, 5]
,用来保存要保留的列索引值。输出文件还要求各个数据元素“以空格隔开”,所以我们在创建对象filewriter
的时候,需要把writer()
函数的delimiter
参数设置为delimiter=' '
。空列表row_list_output
用来保存要输出的数据行。对于满足列索引值为3, 4, 5的数据元素,将其追加到列表row_list_output
中,并将其写入输出文件。
处理四:将test3中的数据读出,每行数据的单个元素用空格隔开,数据行与数据行用逗号隔开,每20个一行写入文件finally中,保证每行不会出现不够或者多出来的情况。
输出finally单行样例
-0.72 9.62 0.14982383,-4.02 11.03 3.445948,0.95 14.71 3.636633,-3.57 5.75 -5.407278,-5.28 8.85 -9.615966,-1.14 15.02 -3.8681788,7.86 11.22 -1.879608,6.28 4.9 -2.3018389,0.95 7.06 -3.445948,-1.61 9.7 0.23154591,6.44 12.18 -0.7627395,5.83 12.07 -0.53119355,7.21 12.41 0.3405087,6.17 12.53 -6.701211,-1.08 17.54 -6.701211,-1.69 16.78 3.214402,-2.3 8.12 -3.486809,-2.91 0 -4.7535014,-2.91 0 -4.7535014,-4.44 1.84 -2.8330324
我的代码
#!/usr/bin/env python3
import csv
import sys
input_file = sys.argv[1]
output_file = sys.argv[2]
with open(input_file, 'r', newline='') as csv_in_file:
with open(output_file, 'w', newline='') as csv_out_file:
filereader = csv.reader(csv_in_file)
filewriter = csv.writer(csv_out_file)
total = []
for row_list in filereader:
total.append(row_list[0])
outputList = []
a_list = []
a = 0
for data in total:
if a < 19:
a += 1
a_list.append(data)
else:
a_list.append(data)
outputList.append(a_list)
a = 0
a_list = []
for output_line in outputList:
filewriter.writerow(output_line)
第13行代码创建了空列表total
,用来保存所有的数据行。第16-17行则是把数据行添加到total
中的过程。第18行创建了空列表outputList
,用来把total
中的数据每20个一组进行拆分。第19行创建的a_list
是辅助拆分列表的列表变量。a
则是一个计数器变量。
遍历列表total
,当a
小于19时,a
自加1,然后把data
添加到a_list
中。当a
等于19时,再把data
添加到a_list
之后,a_list
的长度为20,这时就需要把a_list
添加到outputList
中,然后将a
归零,将a_list
清空,继续下一轮拆分。拆分完成之后,逐行写入输出文件即可。