我的DataFrame观察到错误,即日期不匹配,因为列是通过API无意中生成的日期和值对,如下所示:

data = {'Date.0': ['1/1/2022','1/2/2022', '1/3/2022','1/4/2022'], 'ABC Return': [11, 21, 31, 41], 'Date.1': ['1/1/2022','1/2/2022', '1/4/2022','1/5/2022'], 'XYZ Return': [12, 22, 42, 51] }
df = pd.DataFrame(data)

我想修复这个问题,使它们对齐,并用0(或NaN或其他值)填充缺失的值:

data = {'Date.0': ['1/1/2022','1/2/2022', '1/3/2022','1/4/2022','1/5/2022'], 'ABC Return': [11, 21, 31, 41, np.NaN], 'Date.1': ['1/1/2022','1/2/2022', '1/3/2022', '1/4/2022','1/5/2022'], 'XYZ Return': [12, 22, np.NaN, 42, 51]}
df = pd.DataFrame(data)

我有大约60个变量,但我还没有想出一个可伸缩的解决方案(除了在Excel中手动合并它们之外).如有任何帮助,我们不胜感激.

编辑:请注意,Value列没有系统的模式(除了结尾是相同的"xxx Return")(我已经将它从var1和var2更改为ABC和XYZ.)日期是有编号的,因此确实有一个模式,但略有不同,我已经更新了这个(而不是data_var1,现在是Date.0,Date.1等).

由于我的专栏名称已更改,因此Nick提供的以下解决方案有效,稍作修改:

# get a list of var names
ticker_list = [col for col in df.columns if col.endswith('Return')]
dates = pd.DataFrame(pd.concat([df[f'Date.{v}'] for v in range(2)]).unique()).set_index(0)
date_counter = 0
dfs = list()
for v in tickers:
    dfs.append(dates.join(df[[f'Date.{date_counter}', v]].set_index(f'Date.{date_counter}')).fillna(np.NaN))
    date_counter = date_counter + 1 
out = pd.concat(dfs, axis=1).reset_index(names='date')

推荐答案

有一种方法可以做到这一点(取决于问题中的列命名方案,如果真正的数据帧不使用这些名称,则需要进行调整):

# get a list of var names
vars = [col for col in df.columns if col.startswith('var')]
# make a dataframe with all the unique dates as its index
dates = pd.DataFrame(pd.concat([df[f'date_{v}'] for v in vars]).unique()).set_index(0)
# extract each of the date_var* and var* columns to a separate df
# and join to the list of dates, filling na with 0
dfs = [dates.join(df[[f'date_{v}', v]].set_index(f'date_{v}')).fillna(0) for v in vars]
# concatenate all the dfs together and reset the index
out = pd.concat(dfs, axis=1).reset_index(names='date')

输出(针对您的示例数据):

       date  var1  var2
0  1/1/2022  11.0  12.0
1  1/2/2022  21.0  22.0
2  1/3/2022  31.0   0.0
3  1/4/2022  41.0  42.0
4  1/5/2022   0.0  51.0

Edit

根据对问题的更改,对代码的此修改应执行所需的操作:

ticker_cols = [col for col in df.columns if col.endswith('Return')]
date_cols = [col for col in df.columns if col.startswith('Date')]
dates = pd.DataFrame(pd.concat([df[date] for date in date_cols]).unique()).set_index(0)
dfs = [dates.join(df[[date, ticker]].set_index(date)).fillna(0) for date, ticker in zip(date_cols, ticker_cols)]
out = pd.concat(dfs, axis=1).reset_index(names='date')

输出:

       date  ABC Return  XYZ Return
0  1/1/2022        11.0        12.0
1  1/2/2022        21.0        22.0
2  1/3/2022        31.0         0.0
3  1/4/2022        41.0        42.0
4  1/5/2022         0.0        51.0

Python相关问答推荐

计算每月过go x年的平均值

云上Gunicorn的Flask-socketIO无法工作

在Python中,如何才能/应该使用decorator 来实现函数多态性?

Python中的Pool.starmap异常处理

如何终止带有队列的Python进程?+ 队列大小的错误?

Google Drive API获取文件计量数据

如果索引不存在,pandas系列将通过索引获取值,并填充值

如何在BeautifulSoup中链接Find()方法并处理无?

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

使用mySQL的SQlalchemy过滤重叠时间段

max_of_three使用First_select、second_select、

numba jitClass,记录类型为字符串

按列分区,按另一列排序

更改键盘按钮进入'

Python虚拟环境的轻量级使用

如何请求使用Python将文件下载到带有登录名的门户网站?

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

递归访问嵌套字典中的元素值

Pandas GroupBy可以分成两个盒子吗?

如何防止Pandas将索引标为周期?