【问题标题】:Pandas index match multiple dataframes with multiple criteriaPandas 索引匹配具有多个条件的多个数据帧
【发布时间】:2020-09-13 16:40:56
【问题描述】:

我正在尝试让 python 读取一个 excel 文件,然后从 .csv 文件创建数据框,这些文件以 excel 文件中的行命名,并从 .csv 文件中索引数据并将它们粘贴到 excel 文件中。

excel 文件已放入数据框中,其布局如下:

     Name  Location      Date Check_2  ...  Volume  VWAP  $Volume  Trades
0  Orange  New York  20200501       X  ...     NaN   NaN      NaN     NaN
1   Apple     Minsk  20200504       X  ...     NaN   NaN      NaN     NaN

空行应填充从已放入数据框中的 .csv 文件索引的数据,如下所示:

  Name      Date      Time  Open  High   Low  Close  Volume  VWAP  Trades
4   Orange  20200501  15:30:00  5.50  5.85  5.45   5.70    1500  5.73      95
5   Orange  20200501  17:00:00  5.65  5.70  5.50   5.60    1600  5.65      54
6   Orange  20200501  20:00:00  5.80  5.85  5.45   5.81    1700  5.73      41
7   Orange  20200501  22:00:00  5.60  5.84  5.45   5.65    1800  5.75      62
8   Orange  20200504  15:30:00  5.40  5.87  5.45   5.75    1900  5.83      84
9   Orange  20200504  17:00:00  5.50  5.75  5.40   5.60    2000  5.72      94
10  Orange  20200504  20:00:00  5.80  5.83  5.44   5.50    2100  5.40      55
11  Orange  20200504  22:00:00  5.40  5.58  5.37   5.80    2200  5.35      87
0    Apple  20200504  15:30:00  3.70  3.97  3.65   3.75    1000  3.60      55
1    Apple  20200504  17:00:00  3.65  3.95  3.50   3.80    1200  3.65      68
2    Apple  20200504  20:00:00  3.50  3.83  3.44   3.60    1300  3.73      71
3    Apple  20200504  22:00:00  3.55  3.58  3.35   3.57    1400  3.78      81
4    Apple  20200505  15:30:00  3.50  3.85  3.45   3.70    1500  3.73      95
5    Apple  20200505  17:00:00  3.65  3.70  3.50   3.60    1600  3.65      54
6    Apple  20200505  20:00:00  3.80  3.85  3.45   3.81    1700  3.73      41
7    Apple  20200505  22:00:00  3.60  3.84  3.45   3.65    1800  3.75      62

我一直在努力填充这些空单元格,因为我无法找到一种方法来正确索引这两个数据帧之间的匹配。

例如,尝试:

intradayho = rdf2[(rdf2['Time']=='15:30:00')]
indexopen = pd.DataFrame(intradayho['Open'])

rdf1['Open'] = rdf1.Date.map(intradayho.set_index('Date')['Open'].to_dict())
print("Open prices rdf1")
print(rdf1['Open'])

产生:

Open prices rdf1
0    5.5
1    3.7

但只考虑日期,所以它会复制“日期”列的打开值,而不是“名称”和“日期”,这是一个问题,因为它们是需要匹配的 2 个值。

此外,此代码会产生以下错误:

正在尝试在 DataFrame 中的切片副本上设置值。请尝试改用 .loc[row_indexer,col_indexer] = value

但是当我尝试用

解决这个问题时
rdf1.loc[rdf1['Open']] = rdf1.Date.map(intradayho.set_index('Date')['Open'].to_dict())

我收到一个错误:

KeyError:“[Float64Index([nan, nan], dtype='float64')] 中没有一个在 [index] 中”

这对我来说没有意义,因为整个目标是填充这些“NaN”值。

这里有人可以帮我制作一些可以索引这些数据框中的匹配数据并将其写入 Excel 文件的东西吗?

谢谢!

编辑: 忘了贴我的完整代码,这里是:

import pandas as pd
import os

#Opening 'Test Tracker.xlsx' to find entities to download
TEST = pd.ExcelFile("Trackers\TEST Tracker.xlsx")
df1 = TEST.parse("Entries")

values1 = df1[['Name', 'Location', 'Date', 'Check_2',
           'Open', 'High', 'Low', 'Close', 'Volume', 'VWAP', '$Volume', 
'Trades']]

#Searching for every row that contains the value 'X' in the column 'Check_2'
rdf1 = values1[values1.Check_2.str.contains("X")]

#Printing dataframe to check
print("First Dataframe")
print(rdf1)

#creating a list for the class objects
Fruits = []

#Generating dataframes from classobjects
for idx, rows in rdf1.iterrows():
    fle = os.path.join('Entities', rows.Location, rows.Name, 'TwoHours.csv')
    col_list = ['Name', 'Date', 'Time', 'Open', 'High', 'Low', 'Close', 'Volume', 'VWAP', 'Trades']
    df3 = pd.read_csv(fle, usecols=col_list, sep=";")
    Fruits.append(df3)

rdf2 = pd.concat(Fruits)
print("Printing Full Data Frame")
print(rdf2)

intradayh = rdf2[(rdf2['Time']>'15:30:00') & (rdf2['Time']<'22:00:00')]
intradayho = rdf2[(rdf2['Time']=='15:30:00')]
indexopen = pd.DataFrame(intradayho['Open'])
intradayhc = rdf2[(rdf2['Time']=='22:00:00')]
indexclose = pd.DataFrame(intradayhc['Close'])

rdf1.loc[rdf1['Open']] = rdf1.Date.map(intradayho.set_index('Date')['Open'].to_dict())
print("Open prices rdf1")
print(rdf1['Open'])

编辑:在 cmets 中要求的所需输出:

  Name  Location      Date    Open   High   Low    close  volume  VWAP ...
0  Orange  New York  20200501  5.5    5.95  5.45    5.65   6600   5.71  ...
1   Apple     Minsk  20200504  3.7    3.83  3.35    3.57   4900   3.69 ...

我打算在“打开”中进行 1 对 1 匹配,在“高”中设置最大值,在“低”中设置最小值,在“关闭”中进行 1 对 1 匹配,在“音量”中进行总和值和“交易”。 'VWAP' 的平均值和 '$Volume' 中的 'Volume * VWAP' 的值。

【问题讨论】:

  • 看起来你需要做的只是一个简单的合并。虽然很难理解您的问题。您可以手动构造预期的 2 或 3 行预期输出并共享吗?
  • 感谢您的回复。是的,我用所需的输出更新了帖子
  • 很好,对于公开赛和高赛,您是在寻找 1 对 1 的比赛还是均值?我们也无法在第二个数据框中看到 Apple。请问也可以更新一下吗?论坛的一件事是当人们可以看到输入和输出时,会有快速的答案。
  • 比你小费还好。我将使用整个数据框更新帖子
  • 不是整个数据框!只需举一个最能代表这种情况的样本。

标签: python python-3.x pandas


【解决方案1】:

df,你的 nan datframe 和df2;包含所有数据的更大数据框

groupby.agg() 一起使用可在多个列上查找多个聚合

df2=df1.groupby(['Name','Date']).agg(Open=('Open','first'), Close=('Close','last'),High=('High','max'),Low=('Low','min'),Volume=('Volume','sum'),VWAP=('VWAP','mean')).reset_index()

一种方法是进行内部合并并对更新的列进行切片

result = pd.merge(df2, df, how='inner', on=['Name', 'Date']).iloc[:,:-4]

或 聚合后,使用combine_first并删除所有NaNs

result= (df.set_index('Date').combine_first(df2.set_index('Date')).reset_index())
result=result[k.notna()]

结果

【讨论】:

  • 感谢您的帮助。不幸的是,这似乎无法在我的代码中重现您的结果。它正在返回最终数据帧,但所有值仍然是:NaN。我认为问题在于您的代码出于某种原因调整了列名,因为我的终端将列返回为:“Open_X”、“Close_X”、“Open_Y”、...。因此我认为 python 确实不认识他们,但我不确定。我希望你能帮助解决这个问题
  • 哦,我现在看到你更新了一些东西,我检查一下
  • 代码应该可以工作。只要确保输入正确的列名即可。在agg 函数中,请记住它是.agg(NewName=(ColumnName, function))。在这种情况下,我使NewNameColumnName 相同。只需检查列名就可以了
  • 不幸的是,您的第二个选项对我也不起作用。关于您的代码,我有一些不明白的地方,可能就是这样。你说:df = NaN 数据框,我认为你的意思是第一个数据框(对我来说是 rdf1),它代表 excel 文件。然后你说 df2 = 大的,我明白了。但是在您的代码中,您似乎使用了“df”、“df1”和“df2”,所以我弄乱了这些但没有让它工作。此外,您使用 result=result[k.notna()],但未定义“k”,将其与“result”或“rdf1”交换也不起作用
  • 我的“输出”是:每列中的“NaN”已经为空,如果您想知道的话
猜你喜欢
  • 2015-02-15
  • 2017-10-22
  • 2020-08-03
  • 2013-06-28
  • 2016-07-19
  • 2013-08-30
  • 1970-01-01
  • 2017-01-08
  • 2021-11-16
相关资源
最近更新 更多