使用" VLOOKUP"创建新的数据帧。两个数据帧之间

时间:2017-12-28 21:20:47

标签: python python-3.x pandas

与Excel的VLOOKUP函数有些类似,我想在一个数据帧(下面{{#each computers}} {{#each this}} {{cpu}} {{ram}} {{hd}} {{/each}} {{/each}} )中使用一个值来查找第二个数据帧(下面portfolios)中的关联值使用这些返回值填充第三个数据框(现在让我们调用此dataframe3)。我找到了几个基于左侧合并和returns的帖子,但我原来的两个数据框架结构不同,所以这些方法似乎不适合(至少对我来说)。

我没有取得多大进展,但这是我的代码:

代码

map

数据

如果我第一次描述我的数据,这段代码会更有意义: import pandas as pd portfolios = pd.read_csv('portstst5_1.csv') returns = pd.read_csv('Example_Returns.csv') total_cols = len(portfolios.columns) headers = list(portfolios) concat = returns['PERMNO'].map(str) + returns['FROMDATE'].map(str) idx = 2 returns.insert(loc=idx, column="concat", value=concat) for i in range(total_cols): col_len = portfolios.iloc[:,i].count() for j in range(col_len): print(portfolios.iat[j,i].astype('int').astype('str') + headers[i]) 是一个包含13列不同长度的数据框。列标题是YYYYMMDD格式的日期。每个日期标题下面是五位数字代码的标识符。 portfolios的片段看起来像这样(某些列中的某些元素包含NaN):

portfolios

20131231 20131130 20131031 20130930 20130831 20130731 20130630 \ 0 93044.0 93044.0 13264.0 13264.0 89169.0 82486.0 91274.0 1 79702.0 91515.0 90710.0 81148.0 47387.0 88359.0 93353.0 2 85751.0 85724.0 88810.0 11513.0 85576.0 47387.0 85576.0 数据中的数据最初由三列和799行组成,看起来像这样(所有元素都填充了值):

returns

所需输出

我想制作第三个与 PERMNO FROMDATE MORET 0 93044 20131231 -0.022304 1 79702 20131231 0.012283 2 85751 20131231 -0.016453 3 85576 20131231 0.038766 完全相同的数据框。也就是说,它将与portfolios具有相同的列标题日期和每列中相同的行数,但不是标识符,它将包含适当标识符/日期组合的portfolios。这就是上面代码中连接的原因 - 我正在尝试(可能不必要)创建唯一的查找值,以便我可以在MORETportfolios之间进行通信。例如,要填充returns,我会在dataframe3[0,0]中查找来自portfolios[0,0]headers[0](即9304420131231)的连接值,并返回returns['concat']中的关联值}(即-0.022304)。我被困在这里如何使用连接值来返回我想要的数据。

非常感谢任何想法。

3 个答案:

答案 0 :(得分:1)

您尝试做的事情 比您尝试做的更简单。您可以先将portfolios融化以翻转它,然后将所有日期列收集为一列中的行,然后将其与returns连接,最后转动以获得所需的结果。这基本上是@ djk47463在一个复合行中所做的,我编辑的答案是他的逐步细分。

让我们创建您的DataFrames以使答案可重现。

import pandas as pd
import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

# Create df
rawText = StringIO("""
     PERMNO  FROMDATE     MORET
0     93044  20131231 -0.022304
1     79702  20131231  0.012283
2     85751  20131231 -0.016453
3     85576  20131231  0.038766
4     93044  20131010 -0.02
5     79702  20131010  0.01
6     85751  20131010 -0.01
7     85576  20131010  0.03
""")
returns = pd.read_csv(rawText, sep = "\s+")
portfolios = pd.DataFrame({'20131010':[93044, 85751],
                       '20131231':[85576, 79702]})

请注意,FROMDATE的{​​{1}}列由数字组成,但在returns中,日期列是字符串。我们必须使它们保持一致:

portfolios

让我们通过df.FROMDATE = df.FROMDATE.astype(str) ing(即unpivot)melt启动解决方案:

portfolios

现在您希望保持此portfolios = portfolios.melt(var_name=['FROMDATE'],value_name='PERMNO') # portfolios: FROMDATE PERMNO 0 20131010 93044 1 20131010 85751 2 20131231 85576 3 20131231 79702 常量,并在pmreturns匹配时将PERMNO合并到其行中:

FROMDATE

还记得我们在merged = pm.merge(df, how='left', on=['PERMNO', 'FROMDATE']) # merged: FROMDATE PERMNO MORET 0 20131010 93044 -0.020000 1 20131010 85751 -0.010000 2 20131231 85576 0.038766 3 20131231 79702 0.012283 开始melt编辑(未透露)吗?我们应portfolios将此结果赋予其pivot

的形状
portfolios

答案 1 :(得分:1)

<强> IIUC:

使用melt的组合,我们可以returnsportfolios.columns = portfolios.columns.astype(int) newdf = portfolios.reset_index().melt(id_vars='index',var_name=['FROMDATE'],value_name='PERMNO').merge(returns,on=['FROMDATE','PERMNO'],how='left').pivot(index='index',columns='FROMDATE',values='MORET') 列所需的值。然后使用merge重新整形数据,如下所示。

FROMDATE  20130630  20130731  20130831  20130930  20131031  20131130  20131231
index
0              NaN       NaN       NaN       NaN       NaN       NaN -0.022304
1              NaN       NaN       NaN       NaN       NaN       NaN  0.012283
2              NaN       NaN       NaN       NaN       NaN       NaN -0.016453

返回下面的DataFrame

newdf.loc[:,newdf.columns.sort_values(ascending=False)]

对列进行排序

_id

答案 2 :(得分:0)

在python中执行vlookup的典型方法是创建一个系列,其中包含索引中的左列,然后按查找值对该系列进行切片。 NaNs使它复杂化了一点。我们将returns使用set_index方法设置PERMNO作为数据帧的索引,然后按列名切片以隔离{{1}列为一系列。

MORET