pandas 行之间的减法
Subtraction between rows with pandas
我正在尝试解析一个 csv 文件并打印某些时间序列图。
关于csv文件: csv文件包含大量数据,我需要根据id处理它的confirmedInfections在一个for循环中。 csv 文件如下所示:
ID,name,date,confirmedInfections
DE2,BAYERN,2020-02-24,19
DE2,BAYERN,2020-02-25,19
DE2,BAYERN,2020-02-26,21
DE1,BADEN-WÜRTTEMBERG,2020-02-24,1
DE1,BADEN-WÜRTTEMBERG,2020-02-25,3
DE1,BADEN-WÜRTTEMBERG,2020-02-26,7
从该文件中,我需要解析每一行并减去 confirmedInfections
以找到每日感染。此时如果我选择 ID DE2 and date 2020-03-01
的城市,感染是从开始到我选择的那一天的总和。因此,我需要编辑此文件以减去并找到日常案例以打印正确的时间序列。为了这个减法的目的,我找到了 pandas.shift(1)
方法,但它似乎不起作用。
我的代码:
def main(file):
id_array = ['DE2', 'DE1']
df = pd.read_csv(file, header='infer', parse_dates=['date'])
for key in id_array:
if (df.loc[df['ID'] == key]):
df['confirmedInfections'] = df['confirmedInfections']-df['confirmedInfections'].shift(1)
print(df)
main('data.txt')
期望输出:
#For DE2
ID,name,date,confirmedInfections
DE2,BAYERN,2020-02-24,19
DE2,BAYERN,2020-02-25,0
DE2,BAYERN,2020-02-26,2
#For DE1
ID,name,date,confirmedInfections
DE1,BADEN-WÜRTTEMBERG,2020-02-24,1
DE1,BADEN-WÜRTTEMBERG,2020-02-25,2
DE1,BADEN-WÜRTTEMBERG,2020-02-26,4
我得到的错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
有什么想法吗?
考虑 df 读作:
df = pd.read_csv(file, header='infer', parse_dates=['date'])
根据需要更新“confirmedInfections”列差异:
df["confirmedInfections"] = df.groupby('ID')['confirmedInfections'].diff().fillna(df.confirmedInfections).astype(int)
说明
按 ID 对 df 进行分组并更新行 'confirmedInfections' 列,其中行之间的值存在差异,然后使用原始值更新每个 groupedID 的 NaN(第一行)。由于对 'confirmedInfections' 的计算结果为 float 类型,因此将列类型转换为 int。最后把df拆分成下面的多个df。
在多个 df 中拆分 df
for id in df.ID.unique():
print('DataFrame', id)
print(df.groupby('ID').get_group(id))
输出
DataFrame DE2
ID name date confirmedInfections
0 DE2 BAYERN 2020-02-24 19
1 DE2 BAYERN 2020-02-25 0
2 DE2 BAYERN 2020-02-26 2
DataFrame DE1
ID name date confirmedInfections
3 DE1 BADEN-WÃRTTEMBERG 2020-02-24 1
4 DE1 BADEN-WÃRTTEMBERG 2020-02-25 2
5 DE1 BADEN-WÃRTTEMBERG 2020-02-26 4
您可以使用 diff() 代替 shift() 来解决您的问题。对于其他部分,这可能不是最佳解决方案,但应该可以解决问题 done.Since,您只有你的问题中有两个 ID,并且你想为它们分别创建 DataFrames,我建议先创建两个 DataFrames:
df = pd.read_csv(file_name_with_path, header='infer', parse_dates=['date'])
#since there are only two IDs you can do it this way else there might be some commplex solutions
df_DE1 = df.loc[df.ID == 'DE1']
df_DE2 = df.loc[df.ID == 'DE2']
def get_diff(df):
first_val = df['confirmedInfections'][0] #Need to store the first row value since diff() method would otherwise render it as NaN
df['confirmedInfections'] = df['confirmedInfections'].diff(1)
df['confirmedInfections'][0] = first_val
df_list = [df_DE1, df_DE2]
for df in df_list:
get_diff(df)
我正在尝试解析一个 csv 文件并打印某些时间序列图。
关于csv文件: csv文件包含大量数据,我需要根据id处理它的confirmedInfections在一个for循环中。 csv 文件如下所示:
ID,name,date,confirmedInfections
DE2,BAYERN,2020-02-24,19
DE2,BAYERN,2020-02-25,19
DE2,BAYERN,2020-02-26,21
DE1,BADEN-WÜRTTEMBERG,2020-02-24,1
DE1,BADEN-WÜRTTEMBERG,2020-02-25,3
DE1,BADEN-WÜRTTEMBERG,2020-02-26,7
从该文件中,我需要解析每一行并减去 confirmedInfections
以找到每日感染。此时如果我选择 ID DE2 and date 2020-03-01
的城市,感染是从开始到我选择的那一天的总和。因此,我需要编辑此文件以减去并找到日常案例以打印正确的时间序列。为了这个减法的目的,我找到了 pandas.shift(1)
方法,但它似乎不起作用。
我的代码:
def main(file):
id_array = ['DE2', 'DE1']
df = pd.read_csv(file, header='infer', parse_dates=['date'])
for key in id_array:
if (df.loc[df['ID'] == key]):
df['confirmedInfections'] = df['confirmedInfections']-df['confirmedInfections'].shift(1)
print(df)
main('data.txt')
期望输出:
#For DE2
ID,name,date,confirmedInfections
DE2,BAYERN,2020-02-24,19
DE2,BAYERN,2020-02-25,0
DE2,BAYERN,2020-02-26,2
#For DE1
ID,name,date,confirmedInfections
DE1,BADEN-WÜRTTEMBERG,2020-02-24,1
DE1,BADEN-WÜRTTEMBERG,2020-02-25,2
DE1,BADEN-WÜRTTEMBERG,2020-02-26,4
我得到的错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
有什么想法吗?
考虑 df 读作:
df = pd.read_csv(file, header='infer', parse_dates=['date'])
根据需要更新“confirmedInfections”列差异:
df["confirmedInfections"] = df.groupby('ID')['confirmedInfections'].diff().fillna(df.confirmedInfections).astype(int)
说明 按 ID 对 df 进行分组并更新行 'confirmedInfections' 列,其中行之间的值存在差异,然后使用原始值更新每个 groupedID 的 NaN(第一行)。由于对 'confirmedInfections' 的计算结果为 float 类型,因此将列类型转换为 int。最后把df拆分成下面的多个df。
在多个 df 中拆分 df
for id in df.ID.unique():
print('DataFrame', id)
print(df.groupby('ID').get_group(id))
输出
DataFrame DE2
ID name date confirmedInfections
0 DE2 BAYERN 2020-02-24 19
1 DE2 BAYERN 2020-02-25 0
2 DE2 BAYERN 2020-02-26 2
DataFrame DE1
ID name date confirmedInfections
3 DE1 BADEN-WÃRTTEMBERG 2020-02-24 1
4 DE1 BADEN-WÃRTTEMBERG 2020-02-25 2
5 DE1 BADEN-WÃRTTEMBERG 2020-02-26 4
您可以使用 diff() 代替 shift() 来解决您的问题。对于其他部分,这可能不是最佳解决方案,但应该可以解决问题 done.Since,您只有你的问题中有两个 ID,并且你想为它们分别创建 DataFrames,我建议先创建两个 DataFrames:
df = pd.read_csv(file_name_with_path, header='infer', parse_dates=['date'])
#since there are only two IDs you can do it this way else there might be some commplex solutions
df_DE1 = df.loc[df.ID == 'DE1']
df_DE2 = df.loc[df.ID == 'DE2']
def get_diff(df):
first_val = df['confirmedInfections'][0] #Need to store the first row value since diff() method would otherwise render it as NaN
df['confirmedInfections'] = df['confirmedInfections'].diff(1)
df['confirmedInfections'][0] = first_val
df_list = [df_DE1, df_DE2]
for df in df_list:
get_diff(df)