我有一个CSV文件,其中包含药物(名称)和某些患者的剂量(id)的信息。
CSV文件的结构如下:
id,table,field,count,value
034, meds, name, 1, ator
034, meds, name, 1, ator
034, meds, name, 2, para
035, meds, name, 1, mar
034, meds, name, 3, mar
034, meds, dose, 1, 20
034, meds, dose, 1, 30
034, meds, dose, 2, 30
035, meds, dose, 1, 20
034, meds, dose, 3, 10
目标是将其解析为“长”格式,并包含以下列:“ id”,“ table”(代码中给出的表名),字段(即名称,dose),值(即例如名称或剂量的值)。到目前为止,我已经成功地将原始CSV结构格式化为该格式。
但是,我还想要一列“计数”,其中包含每个患者服用药物的增量。 例如,编号为034的患者服用了三种药物(先天,后天和三月),对应于计数1、2和3。因此,所需的输出如下:
import pandas as pd
# load the data into a pandas table:
file = '~/data/meds.csv'
df = pd.read_table(file, delimiter=',')
#### CANNOT GET THIS PART TO WORK: #####
count = []
for index, row in df.iterrows():
count.append(df[(df['id'] == row['id']) & (df['name'] < row['name'])].shape[0])
df['count'] = count
########################################
# convert data frame into the long format
df = pd.melt(df, id_vars=['id', 'count'], var_name='field', value_name='value')
# Change all NaNs to None
df = df.where((pd.notnull(df)), None)
# creating new column with table name
table = []
df['table'] = 'meds'
# save to file:
df.to_csv('~/data/meds_out.csv', encoding='utf-8')
每次患者(即身分证)获得新药物(即姓名)时,“计数”应代表表中稍后列出的与例如剂量相对应的药物。
但是我正在努力获得像这样的计数列。
我尝试通过我的代码(请参见下文)将计数列添加到数据框中,但是没有运气。
任何用于创建此列的帮助都将非常有用!
{{1}}
答案 0 :(得分:1)
将melt
与GroupBy.cumcount
一起用于计数器列:
df = pd.melt(df, id_vars='id', var_name='field', value_name='value')
#if constant value set this way
df['table'] = 'meds'
df['count'] = df.groupby(['id','field']).cumcount() + 1
#change order of columns if necessary
df = df[['id','table','field','count','value']]
print (df)
id table field count value
0 34 meds name 1 ator
1 34 meds name 2 para
2 35 meds name 1 mar
3 34 meds name 3 mar
4 34 meds dose 1 20
5 34 meds dose 2 30
6 35 meds dose 1 20
7 34 meds dose 3 10
编辑:
df['count'] = df.groupby('id')['name'].cumcount() + 1
df['count'] = df.groupby('id')['count'].ffill().astype(int)
df = pd.melt(df, id_vars=['id','count'], var_name='field', value_name='value')
print (df)
id count field value
0 34 1 name ator
1 34 2 name ator
2 34 3 name para
3 35 1 name mar
4 34 4 name mar
5 34 1 dose 20
6 34 2 dose 30
7 34 3 dose 30
8 35 1 dose 20
9 34 4 dose 10