[英]How to parse csv file in python to get this output?
我有一個 csv 文件,其中包含類似的數據
樣品 csv
姓名 | 開始 | 結尾 |
---|---|---|
約翰 | 12:00 | 13:00 |
約翰 | 12:10 | 13:00 |
約翰 | 12:20 | 13:20 |
湯姆 | 12:00 | 13:10 |
約翰 | 13:50 | 14:00 |
傑瑞 | 14:00 | 14:30 |
愛麗絲 | 15:00 | 16:00 |
傑瑞 | 11:00 | 15:00 |
樣品 output
不同人花費的平均時間是:
約翰 (60+50+60+10)/4 分鍾湯姆 (70)/1 分鍾傑瑞 (30+240)/2 分鍾愛麗絲 (60)/1 分鍾
我嘗試通過 python csv 解析 csv 文件
import datetime
import csv
with open('people.csv', 'r') as file:
reader = csv.DictReader(file)
for row in reader:
print(row['Start'],row['End'])
但是我無法解析具有特定行名屬於 Jerry 的列並找到他們時間的差異。
以防傑瑞花費最多時間
前 - 約翰 [12:00,13:00],[12:10,13:00],[12:20,13:20],[13:50,14:00]
output - [12:00,13:20],[13:50,14:00]
任何幫助將不勝感激。
如果您願意為此使用 pandas,下面的代碼可以完成這項工作 -
import pandas as pd
df = pd.read_csv("data.csv")
df = df.apply(pd.to_datetime, errors = "ignore")
time_df = df.iloc[:, 1:].diff(axis = 1).drop(columns = "Start").rename(columns = {"End" : "Time Diff"})
time_df["Name"] = df["Name"]
time_df.groupby("Name").mean()
Output -
時差 | |
---|---|
愛麗絲 | 0 天 01:00:00 |
傑瑞 | 0 天 02:15:00 |
約翰 | 0 天 00:45:00 |
湯姆 | 0 天 01:10:00 |
代碼說明 -
代碼中的第 3 行讀取您擁有的 csv 文件並將其轉換為 pandas dataframe。 dataframe 只是一個表,可以以相同的方式進行操作。
代碼中的第 4 行將有效列中的所有值轉換為日期時間,這可以幫助您找到時差。 我已將參數errors = "ignore"
作為 dataframe 中的第一列傳遞,列Name
具有無法轉換為日期時間的字符串值。 將errors
參數作為ignore
傳遞將允許我保留該列的所有原始值。
第 5 行代碼從索引 1 開始選擇列並減去它們。 完成后,將實施drop
function 並具有 null 值的冗余列。 完成后, rename
function 開始並將End
列重命名為Time Diff
。 所有這些都存儲在名為time_df
的新變量中。
因為time_df
中沒有 name 列,所以第 6 行添加了它。
一旦我有了所需的 dataframe,我只需根據Name
列對數據進行分組,這意味着屬於特定人員的所有數據都將單獨處理。 這對我們來說是理想的,因為我們想找到每個人的平均時間。 為此,我們只需在分組數據上應用mean
function,瞧,我們得到了所需的 output。
不帶 Pandas:
times = {}
with open('people.csv', 'r') as file:
reader = csv.DictReader(file)
for row in reader:
if row['name'] not in times.keys():
times[row['name']] = []
times[row['name']].append(row['End'] - row['Start'])
for person in times.keys():
print(person + ": " + str(sum(times[person]) / len(times[person])))
下面是一個簡化的代碼。 您可以使用 pandas 以更少的行數和更少的行數編寫它。
import csv
from datetime import datetime
avg = {}
with open('people.csv', mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file)
for row in csv_reader:
name = row["Name"]
start_time = datetime.strptime(row["Start"], "%H:%M")
end_time = datetime.strptime(row["End"], "%H:%M")
time_taken = (end_time - start_time).total_seconds() / 60.0
if name not in avg.keys():
avg[name] = [time_taken,1]
else:
prev_time_total = avg[name][0]
prev_count = avg[name][1]
new_time_total = prev_time_total + time_taken
new_count = prev_count + 1
avg[name] = [new_time_total,new_count]
for entry in avg:
print(entry,avg[entry][0]/avg[entry][1])
這是另一種不使用pandas
的方法 -
from datetime import datetime, timedelta
with open("data.csv", "r") as f:
f = csv.DictReader(f)
data = [row for row in f]
diffs = {list(row.values())[0]: [] for row in data}
for row in data:
vals = list(row.values())
diffs[vals[0]].append(datetime.strptime(vals[2], "%H:%M") - datetime.strptime(vals[1], "%H:%M"))
diffs_avg = [str(timedelta(seconds = sum(map(timedelta.total_seconds, times)) / len(times))) for times in diffs.values()]
dict(zip(diffs.keys(), diffs_avg))
Output -
{'Alice': '1:00:00', 'Jerry': '2:15:00', 'John': '0:45:00', 'Tom': '1:10:00'}
用 pandas 計算每個人的平均和最大時間(以分鍾為單位):
import pandas as pd
df = (pd.read_csv('file_01.csv',parse_dates=['Start','End']).
assign(diff=(df1.End-df1.Start).dt.total_seconds()//60).
groupby('Name')['diff'].
agg(['mean','max']))
print(df)
'''
mean max
Name
Alice 60.0 60.0
Jerry 135.0 240.0
John 45.0 60.0
Tom 70.0 70.0
'''
df.to_dict()
>>> out
'''
{'mean': {'Alice': 60.0, 'Jerry': 135.0, 'John': 45.0, 'Tom': 70.0},
'max': {'Alice': 60.0, 'Jerry': 240.0, 'John': 60.0, 'Tom': 70.0}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.