Python 如何基于某个CSV文件行中的日期,在特定日期之间将该文件的值传输到另一个CSV文件?

Python 如何基于某个CSV文件行中的日期,在特定日期之间将该文件的值传输到另一个CSV文件?,python,pandas,dataframe,csv,Python,Pandas,Dataframe,Csv,长问题:我有两个CSV文件,一个名为SF1的文件有季度数据(一年只有4次)和datekey列,另一个名为DAILY的文件每天提供数据。这是财务数据,因此有股票代码列 我需要抓取SF1的季度数据,并将其写入每日csv文件中,在我们获得下一个季度数据的所有日期之间 例如,AAPL在SF1中发布了2010-01-01的季度数据,其下一份收益报告将于2010-03-04发布。然后,我需要在日期2010-01-01到2010-03-04之间,每日文件中带有tickerAAPL的每一行具有与SF1文件中该日

长问题:我有两个CSV文件,一个名为SF1的文件有季度数据(一年只有4次)和datekey列,另一个名为DAILY的文件每天提供数据。这是财务数据,因此有股票代码列

我需要抓取SF1的季度数据,并将其写入每日csv文件中,在我们获得下一个季度数据的所有日期之间

例如,
AAPL
在SF1中发布了2010-01-01的季度数据,其下一份收益报告将于2010-03-04发布。然后,我需要在日期2010-01-01到2010-03-04之间,每日文件中带有ticker
AAPL
的每一行具有与SF1文件中该日期的那一行相同的信息

到目前为止,我已经制作了一个python字典,它遍历SF1文件并将日期添加到一个列表中,该列表是字典中ticker键的值。我考虑过去掉前面的字符串,只引用字典中的字符串,然后搜索要写入日常文件的数据

从SF1文件传输到每日文件所需的某些列包括:

['acoci'、'assetsavg'、'assetsc'、'assetsnc'、'assettover'、'bvps'、'capex'、'cashneq'、'cashnequsd'、'cor'、'consolinc'、'currentratio'、'de'、'debtc'、'debtc'、'debertredrev'、'depamor'、'存款'、'divyield'、'dps'、'ebit']

迄今为止的代码:

for ind, row in sf1.iterrows():
    sf1_date = row['datekey']
    sf1_ticker = row['ticker']
    company_date.setdefault(sf1_ticker, []).append(sf1_date)
解决这个问题的最好办法是什么

SF1 csv:

ticker,dimension,calendardate,datekey,reportperiod,lastupdated,accoci,assets,assetsavg,assetsc,assetsnc,assetturnover,bvps,capex,cashneq,cashnequsd,cor,consolinc,currentratio,de,debt,debtc,debtnc,debtusd,deferredrev,depamor,deposits,divyield,dps,ebit,ebitda,ebitdamargin,ebitdausd,ebitusd,ebt,eps,epsdil,epsusd,equity,equityavg,equityusd,ev,evebit,evebitda,fcf,fcfps,fxusd,gp,grossmargin,intangibles,intexp,invcap,invcapavg,inventory,investments,investmentsc,investmentsnc,liabilities,liabilitiesc,liabilitiesnc,marketcap,ncf,ncfbus,ncfcommon,ncfdebt,ncfdiv,ncff,ncfi,ncfinv,ncfo,ncfx,netinc,netinccmn,netinccmnusd,netincdis,netincnci,netmargin,opex,opinc,payables,payoutratio,pb,pe,pe1,ppnenet,prefdivis,price,ps,ps1,receivables,retearn,revenue,revenueusd,rnd,roa,roe,roic,ros,sbcomp,sgna,sharefactor,sharesbas,shareswa,shareswadil,sps,tangibles,taxassets,taxexp,taxliabilities,tbvps,workingcapital
A,ARQ,2020-09-14,2020-09-14,2020-09-14,2020-09-14,53000000,7107000000,,4982000000,2125000000,,10.219,-30000000,1368000000,1368000000,1160000000,131000000,2.41,0.584,665000000,111000000,554000000,665000000,281000000,96000000,0,0.0,0.0,202000000,298000000,0.133,298000000,202000000,202000000,0.3,0.3,0.3,4486000000,,4486000000,50960600000,,,354000000,0.806,1.0,1086000000,0.484,0,0,4337000000,,1567000000,42000000,42000000,0,2621000000,2067000000,554000000,51663600000,1368000000,-160000000,2068000000,111000000,0,1192000000,-208000000,-42000000,384000000,0,131000000,131000000,131000000,0,0,0.058,915000000,171000000,635000000,0.0,11.517,,,1408000000,0,114.3,,,1445000000,131000000,2246000000,2246000000,290000000,,,,,0,625000000,1.0,452000000,439000000,440000000,5.116,7107000000,0,71000000,113000000,16.189,2915000000
每日csv:

ticker,date,lastupdated,ev,evebit,evebitda,marketcap,pb,pe,ps
A,2020-09-14,2020-09-14,31617.1,36.3,26.8,30652.1,6.2,44.4,5.9
代码运行后的理想csv(包括其下资产的所有编号):


解决方案是
merge\u asof
它允许将日期列合并到第二个数据帧中紧跟其后或之前的位置

由于不明确,我在这里假设
daily.date
sf1.datekey
都是真正的日期列,这意味着它们的数据类型是
datetime64[ns]
merge\u asof
不能将字符串列与
对象一起使用

我还假设您不希望使用
sf1
数据帧中的ev-evebit-evebitda-marketcap-pb-pe和ps列,因为它们的名称与
daily
中的列冲突(稍后将详细介绍):

代码可以是:

df = pd.merge_asof(daily, sf1.drop(columns=['dimension', 'calendardate',
                                            'reportperiod','lastupdated',
                                            'ev', 'evebit', 'evebitda',
                                            'marketcap', 'pb', 'pe', 'ps']),
                                   by = 'ticker', left_on='date',
                                   right_on='datekey')
您可以获得以下列列表:股票代码、日期、最新更新、ev、EVBIT、EVBITDA、marketcap、pb、pe、ps、datekey、accoci、assets、assetsavg、assetsc、assetsnc、assetturnover、bvps、capex、cashneq、cashnequsd、cor、consolinc、currentratio、de、debt、debtc、debt USD、deferredrev、depamor、存款、股息收益率、dps、ebit、ebitda、,息税折旧摊销前利润、息税折旧摊销前利润、息税折旧摊销前利润、息税折旧摊销前利润、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益、每股收益,净利润、运营成本、opinc、应付款项、支付比率、pe1、ppnenet、预除数、价格、ps1、应收账款、再收益、收入、收益、rnd、roa、roic、ros、sbcomp、sgna、股票因子、股票期权、股票互换、sps、有形资产、税务资产、税收负债、TBVP、,营运资本及其相关价值


如果要使两个数据帧中的列都存在,则必须重命名它们。下面是一个可能的代码,用于将
\u d
添加到每日的列名称中:

df2 = pd.merge_asof(daily, sf1.drop(columns=['dimension', 'calendardate',
                                            'reportperiod','lastupdated']),
                                   by = 'ticker', left_on='date',
                                   right_on='datekey', suffixes=('_d', ''))

现在列的列表是:ticker、date、lastupdated、ev_d、evebit_d、evebitda_d、marketcap_d、pb_d、pe_d、ps_d、datekey、accoci,…

你能提供一个显示一些CSV行和所需输出的简化示例吗?@MartinEvans刚刚这样做了,希望能有所帮助:)回答得很好!我现在改变了一些小事情,我得到了一个错误。对于SF1文件,我现在使用
calendardate
而不是datekey。我还按照ticker和date/calendardate值对数据帧进行了排序。代码:df=pd.merge\u asof(daily,sf1,by='ticker',left\u on='date',right\u on='calendardate',tolerance=pd.Timedelta(value=100,unit='D'),direction='backward')pandas.errors.MergeError:键必须是整数或时间戳
@george.adams1:您控制了日期和日历日期的数据类型吗?这必须是
datetime64[ns]
…我现在刚刚修复了它。我遇到了另一个问题:
ValueError:必须对左键进行排序
我以前以为我已经解决了这个问题,但我想我没有解决。在尝试对数据帧进行排序之前,我添加了以下代码行:
daily=daily.sort\u values('date',升序=True)sf1=sf1.sort\u values('calendardate',升序=True)daily=daily.sort\u values('ticker')sf1=sf1.sort\u values('ticker')
您可以(也应该……)即使对于多个列,也要一次完成排序:
daily=daily.sort_值(['ticker',date'])
。我将代码更改为:
daily=daily.sort_值(['ticker',date'])sf1=sf1.sort_值(['ticker',calendardate'])
我仍然会遇到这个错误:
ValueError:左键必须按什么顺序排序
merge\u asof
才能工作?
df2 = pd.merge_asof(daily, sf1.drop(columns=['dimension', 'calendardate',
                                            'reportperiod','lastupdated']),
                                   by = 'ticker', left_on='date',
                                   right_on='datekey', suffixes=('_d', ''))