使用pandas在字典中的dataframes中插入行和删除行

使用pandas在字典中的dataframes中插入行和删除行,pandas,date,dataframe,dictionary,Pandas,Date,Dataframe,Dictionary,我有一个包含多个数据帧的字典,我的数据帧(示例df1和df2)具有相同的结构。dict中每个数据帧的键是数据帧中显示的id(因此对于df1为“AA”) 我有一个数据框(data_extract),不在字典中,我想用相同的id将该数据框中的日期添加到字典中的数据框中,然后添加一个值,然后删除data_extract中日期之前的所有日期。最后我想要像df1_bis和df2_bis这样的东西 我曾考虑过使用concat,但我不确定这是否是最好的主意,因为在我的脚本中,我需要删除一些行,我认为修改每个数

我有一个包含多个数据帧的字典,我的数据帧(示例df1和df2)具有相同的结构。dict中每个数据帧的键是数据帧中显示的id(因此对于df1为“AA”)

我有一个数据框(data_extract),不在字典中,我想用相同的id将该数据框中的日期添加到字典中的数据框中,然后添加一个值,然后删除data_extract中日期之前的所有日期。最后我想要像df1_bis和df2_bis这样的东西

我曾考虑过使用concat,但我不确定这是否是最好的主意,因为在我的脚本中,我需要删除一些行,我认为修改每个数据帧更有效、更符合逻辑。对于日期,我考虑过使用日历日,但我不知道这是否是一个好主意以及如何使用它

a = pd.concat(mydict.values(), ignore_index=True)

df1 = pd.DataFrame({'id': ['AA', 'AA','AA', 'AA','AA'],
                    'date' : ['01/01/2015', '07/01/2015','19/01/2015', '01/02/2015','08/02/2015'],
                    'value' :  [7,9,1,6,7],
                    'date_y' : [1,7,19,32,39]
                            })

df2 = pd.DataFrame({'id': ['BB', 'BB','BB', 'BB','BB'],
                    'date' : ['09/01/2015', '17/01/2015','19/02/2015', '01/03/2015','08/03/2015'],
                    'value' :  [8,9,9,6,17],
                    'date_y' : [9,17,50,60,67],
                            })

data_extract = pd.DataFrame({'id': ['AA', 'BB'],
                    'date' : ['03/02/2015', '01/02/2015']
                            })


df1_bis = pd.DataFrame({'id': ['AA', 'AA','AA'],
                    'date' : ['01/02/2015','03/02/2015','08/02/2015'],
                    'value' :  [6,'something',7],
                    'date_y' : [32,34 ,39]
                            })

df2_bis = pd.DataFrame({'id': ['BB', 'BB','BB', 'BB','BB'],
                    'date' : ['17/01/2015', '01/02/2015','19/02/2015', '01/03/2015','08/03/2015'],
                    'value' :  [9,'something',9,6,17],
                    'date_y' : [17,32, 50,60,67],
                            })

这是一个很难回答的问题1.我把步骤分解了

merge_asof, bffil, dropna, concat,sort_values,reindex,MultiIndex,groupby, interpolate

第一部分

清除数据,将日期转换为
datetime
格式,并对值进行排序(
sort\u values
),以便将来合并

df1.date=pd.to_datetime(df1.date,dayfirst=True)
data_extract.date=pd.to_datetime(data_extract.date,dayfirst=True)
df2.date=pd.to_datetime(df2.date,dayfirst=True)
data_extract=data_extract.assign(key=1).sort_values('date')
df=pd.concat([df1,df2]).sort_values('date')

第二部分

使用
merge\u asof
根据您的情况进行合并,并检查其工作方式`


第三部分

修改结果数据框,删除那些小于目标日期的日期,请注意,我在
ffill
中使用了
limit
1,因为您需要在日期之前保留较少的第一行

Yourdf['key']=Yourdf.groupby('id').key.bfill(limit=1)

Yourdf=Yourdf.dropna(subset=['key'])
Yourdf=pd.concat([Yourdf,data_extract],sort=False)

第四部分

使用
interpolate
groupby
data\u extract
中的值填充
date\u y
中缺少的值

idx=pd.MultiIndex.from_arrays([Yourdf.id,Yourdf.date])
Yourdf['date_y']=Yourdf.groupby('id').apply(lambda x : x.set_index('date').date_y.interpolate('index')).reindex(idx).values

Yourdf['value'].fillna('something',inplace=True)

Yourdf.sort_values(['id','date'],inplace=True)


Yourdf.drop('key',1,inplace=True)

第五


谢谢在我的示例df1、df2和data_extract中,我有一个问题,它们有一个同名的列“date”,但在我的脚本中它们有不同的名称。df1和df2有一个名为“date_observed”的列,data_extract的日期列名为“date_event”。在merge
Yourdf=pd.merge\u asof(right\u on='date\u event',left\u on='date\u observed')
期间,我能够克服这个问题,但这是有问题的,因为我的日期在两个不同的列中,并且有一堆NaT。一个简单的解决方案是重命名列,但如果有可能的话,这将非常有用。@JulienAzhar是的,您可以重命名它们,因为您提到两个DFS具有相同的结构;没有什么对您来说是困难的;)@文本他是对的,你的回答对初学者很有帮助!我有一个问题,
idx=pd.MultiIndex.from_数组([Yourdf.id,Yourdf.date])
引发错误
无法处理非唯一的多索引我认为这是因为在某些情况下,我的数据帧(df1、df2等)和数据提取有一个共同的日期。例如,如果我有
data\u extract=pd.DataFrame({'id':['BB'],'date':['19/02/2015']})
我会有
Yourdf=pd.DataFrame({'id':['BB','BB','BB'],'date':['19/02/2015','01/03/2015','08/03/2015'],'08/03'],'value','9,6,17,'date y':[50,60,67]})
@JulienAzhar我想您在df1或df2中有重复的日期检查:-)
idx=pd.MultiIndex.from_arrays([Yourdf.id,Yourdf.date])
Yourdf['date_y']=Yourdf.groupby('id').apply(lambda x : x.set_index('date').date_y.interpolate('index')).reindex(idx).values

Yourdf['value'].fillna('something',inplace=True)

Yourdf.sort_values(['id','date'],inplace=True)


Yourdf.drop('key',1,inplace=True)
#check the result 
Yourdf
Out[1036]: 
   id       date      value  date_y
5  AA 2015-02-01          6    32.0
0  AA 2015-02-03  something    34.0
6  AA 2015-02-08          7    39.0
3  BB 2015-01-17          9    17.0
1  BB 2015-02-01  something    32.0
7  BB 2015-02-19          9    50.0
8  BB 2015-03-01          6    60.0
9  BB 2015-03-08         17    67.0