Python 熊猫:在一个类别中满足多个条件的所有结果
我的数据框中有65K条记录,如下面的代码片段:Python 熊猫:在一个类别中满足多个条件的所有结果,python,pandas,dataframe,querying,Python,Pandas,Dataframe,Querying,我的数据框中有65K条记录,如下面的代码片段: Scrip Timestamp1 NSETS NSEPr Buyq1 Buyq2 Buyq3 Buyq4 Buyq5 Sellq1 Sellq2 Sellq3 Sellq4 Sellq5 Sellp1 Sellp2 Sellp3 Sellp4 Sellp5 buyp1 buyp2 buyp3 buyp4 buyp5 ActPr TotalB
Scrip Timestamp1 NSETS NSEPr Buyq1 Buyq2 Buyq3 Buyq4 Buyq5 Sellq1 Sellq2 Sellq3 Sellq4 Sellq5 Sellp1 Sellp2 Sellp3 Sellp4 Sellp5 buyp1 buyp2 buyp3 buyp4 buyp5 ActPr TotalBuyQty TotalSellQty
ALANKIT 2018-01-12 13:02:06 2018-01-12 13:00:50 78.10 759.00 100.00 996.00 1287.00 200 15.00 300.00 100.00 1787.00 5614.00 78.25 78.35 78.40 78.45 78.50 78.10 78.05 78.00 77.80 77.75 78.25 63928 194206
ALANKIT 2018-01-12 13:32:29 2018-01-12 13:22:21 79.50 28.00 100.00 200.00 1288.00 248 50.00 178.00 898.00 100.00 487.00 79.50 79.55 79.60 79.65 79.75 79.30 79.15 79.10 79.05 78.80 79.20 61927 175983
ALANKIT 2018-01-12 13:36:26 2018-01-12 13:34:51 79.20 39.00 3649.00 1287.00 7.00 11 1500.00 1024.00 1000.00 220.00 65.00 79.20 79.25 79.50 79.55 79.60 79.15 79.00 78.85 78.65 78.55 79.00 65503 176990
ALANKIT 2018-01-12 14:32:29 2018-01-12 14:31:23 78.80 810.00 1000.00 1287.00 1342.00 555 58.00 20.00 100.00 10.00 1250.00 78.80 78.85 78.90 78.95 79.00 78.70 78.60 78.55 78.50 78.30 78.70 84405 184759
ALANKIT 2018-01-12 14:12:58 2018-01-12 14:11:22 78.50 1.00 5.00 100.00 25.00 510 2542.00 25.00 95.00 50.00 500.00 78.50 78.55 78.60 78.85 78.90 78.30 78.25 78.20 78.15 78.10 78.85 74505 189866
APEX 2018-03-05 14:14:30 2018-03-05 14:13:23 72.00 51.00 71.00 20.00 150 1.00 1.00 14.00 20.00 1108.00 690.00 690.15 690.80 690.95 691.00 689.60 689.55 689.45 689.15 689.00 0 35535 61963 690.00
APEX 2018-01-31 11:52:11 2018-01-31 11:50:48 100.00 10.00 10.00 15.00 50 50.00 50.00 10.00 16.00 67.00 621.15 621.20 621.40 621.80 621.95 619.50 619.00 618.00 617.00 616.50 0 8083 25609 619.50
APEX 2018-01-31 11:56:14 2018-01-31 11:54:48 38.00 29.00 67.00 174.00 124 53.00 50.00 50.00 16.00 25.00 625.00 625.40 625.45 626.00 626.90 623.95 623.90 623.50 623.45 623.00 0 12587 23399 624.00
APEX 2018-01-18 09:36:03 2018-01-18 09:35:14 38.00 46.00 67.00 226.00 6 5.00 50.00 36.00 20.00 30.00 781.00 781.80 781.85 781.95 782.00 780.20 780.15 780.05 780.00 779.95 782.70 17023 21946 780.75
APEX 2018-01-18 09:44:16 2018-01-18 09:42:15 47.00 50.00 25.00 67.00 2887 25.00 8.00 58.00 5.00 50.00 791.60 791.65 791.95 792.30 792.65 790.20 790.15 790.00 789.05 789.00 791.45 22314 26007 790.05
STRTECH 2018-01-19 14:57:51 2018-01-19 14:56:24 68.50 1.00 5.00 2.00 3 3.00 20.00 3.00 5.00 10.00 2484.95 2485.00 2489.00 2489.90 2490.00 2477.55 2477.50 2477.20 2477.05 2476.70 2480.60 32408 8565 2485.00
STRTECH 2018-01-25 10:50:10 2018-01-25 10:47:46 32.65 1.00 511.00 1.00 12 9.00 5.00 100.00 23.00 20.00 2484.60 2484.70 2484.80 2485.00 2486.00 2480.15 2480.10 2480.00 2475.00 2471.15 2534.60 28306 18002 2484.70
在相同的纸条和相同的日期中(从字段Timestamp1),我想查询满足2个复杂条件的所有记录和返回记录这些条件是:
a) NSEPr值应至少比当天的第一个NSEPr值高3.5%(可从此处的Timetamp1中提取日期)
b) SellQ1+SellQ2的值之和。。(tillSell 5)应为3倍(或高于BuyQ1+BuyQ2..(tillBuyQ5)的值之和) 我设法使用df['mydt']=df.timestamp1.dt.Date.从timestamp1提取日期。
我尝试通过df.iterrows()使用for循环来完成上述任务,即在df上迭代。由于循环无休止,这失败了。
我记得使用df.groupby['Scrip','mydt']可以实现上述目标 或者使用df.groupby['scrip','mydt'].apply(lambda x
然而,我无法找到解决这个问题的办法。 我将非常感谢您在上述方面的帮助 TIA.它看起来像:
# get the first values per scrip and day
df_a_first_vals= df.groupby([df['Timestamp1'].dt.date, df['Scrip']]).agg({'NSEPr': 'first'})
# create an indexer for condition b and extract the
# corresponding data with the date stored in a separate
# column
df_b_indexer= df[['Sellq1', 'Sellq2', 'Sellq3', 'Sellq4', 'Sellq5']].sum(axis='columns') >= df[['Buyq1', 'Buyq2', 'Buyq3', 'Buyq4', 'Buyq5']].sum(axis='columns')*3
df_b_data= df[df_b_indexer].copy(deep=True)
df_b_data['Timestamp1_date']= df_b_data['Timestamp1'].dt.date
# merge a and b to apply condition a
df_ab_merged= df_b_data.merge(df_a_first_vals, left_on=['Timestamp1_date', 'Scrip'], right_index=True, suffixes=['', '_first'])
# output the result
df_ab_merged[df_ab_merged['NSEPr']>=df_ab_merged['NSEPr_first']*1.035]
似乎您的数据不包含这样的记录,所以我只是将(APEX,2018-01-31T11:52:11)
的NSEPr值从100.00更改为20.00。然后,上面的逻辑输出当天的第二行:
Out[148]:
Scrip Timestamp1 NSETS NSEPr ... TotalBuyQty TotalSellQty Timestamp1_date NSEPr_first
7 APEX 2018-01-31 11:56:14 2018-01-31 11:54:48 38.0 ... 23399 624.0 2018-01-31 20.0
[1 rows x 29 columns]
顺便说一句,如果您的数据非常大,并且您希望避免上面的深度复制,那么您可以将timestam1
的日期部分存储为一个单独的列
Testdata(我刚刚手动更改了最后一条记录,因此它符合条件):
结果:
Out[212]:
Scrip Timestamp1 NSETS NSEPr ... TotalBuyQty TotalSellQty Timestamp1_date NSEPr_first
11 STRTECH 2018-01-19 15:50:10 2018-01-25 10:47:46 32.65 ... 18002 2484.7 2018-01-19 20.5
[1 rows x 29 columns]
检查这是否适合你 首先,我们按纸条和时间戳1分组
grouped = df.groupby(['Scrip','Timestamp1'])
现在,我们使用分组数据帧并检查哪些行符合我们的条件。
符合价格条件的行可以如下获得
price_condition=[]
for g_idx, group in grouped:
for row_idx, row in group.iterrows():
if (row.NSEPr > (group.NSEPr.values[0]*1.035)) :
price_condition.append(row_idx)
else:
pass
df.iloc[price_condition]
pnq_condition=[]
for g_idx, group in grouped:
for row_idx, row in group.iterrows():
if (((row.Sellq1+row.Sellq2+row.Sellq3+row.Sellq4++row.Sellq5) >
(3*(row.Buyq1 + row.Buyq2+ row.Buyq3+ row.Buyq4+ row.Buyq5)))
and (row.NSEPr > (group.NSEPr.values[0]*1.035))) :
pnq_condition.append(row_idx)
else:
pass
df.iloc[price_condition]
符合数量条件的行可以按如下方式获得(此代码中仅使用2个数量)
现在可以得到满足这两个条件的行,如下所示
price_condition=[]
for g_idx, group in grouped:
for row_idx, row in group.iterrows():
if (row.NSEPr > (group.NSEPr.values[0]*1.035)) :
price_condition.append(row_idx)
else:
pass
df.iloc[price_condition]
pnq_condition=[]
for g_idx, group in grouped:
for row_idx, row in group.iterrows():
if (((row.Sellq1+row.Sellq2+row.Sellq3+row.Sellq4++row.Sellq5) >
(3*(row.Buyq1 + row.Buyq2+ row.Buyq3+ row.Buyq4+ row.Buyq5)))
and (row.NSEPr > (group.NSEPr.values[0]*1.035))) :
pnq_condition.append(row_idx)
else:
pass
df.iloc[price_condition]
我可以分别检查满足价格条件和数量条件的值。但是,在您提供的数据中,没有同时满足这两个条件的行。因此,请检查您的完整数据,让我们知道此代码是否适用于您。您希望输出是什么样的?这真的是一个基于用户inpu执行的查询吗t?都给出了,日期和纸条?还是要列出满足此条件的所有记录(所有日期和纸条值)?输出应该是..类似:列出满足2个条件的所有记录是否可能上述数据中没有这样的行?是否可能相反,您希望第一个值高于当前值?结果行似乎不正确。这两个的SellQ1+SellQ2..(tillSell 5)是447&BuyQ1+BuyQ(tillBuyQ5)是776所以,销售数量不是3倍(或更高)比购买量大。还是我遗漏了什么?同意Mohanys的说法,我用我的数据尝试了这一点,但NSEPr增加条件似乎满足了,另一个与Buyq和SellQ之和比较不满足。谢谢你的检查!可能你自己已经发现了错误。我在错误的一侧乘以了三个。从我所得到的e在线阅读这可以通过使用df.groupby['Scrip','mydt']实现。应用,或者可能通过使用df.groupby['Scrip','mydt']实现。应用(lambda x..Mydt是来自时间戳字段的DatePart。如果我们使用apply/lambda,我认为这不能用apply来完成。您可以将最后一个代码段作为函数,并将其应用到数据帧上,但它本质上是相同的。为什么apply需要这么多?。apply是首选的,因为它是一种更干净、更有效的方法来实现相同的结果。在创建变量df_a_first_vals后,可通过自定义函数应用实现。