python的pandas数据处理问题

这是一个股票交易委托数据表,需要对时间处于[93000000,145700000)的每笔委托单进行数据处理(93000000时间之前的数据已经处理完)。

img

img

# 盘中实时匹配计算
df_pz = df[(df['时间'] >= 93000000) & (df['时间'] < 145700000)] # 取集合竞价的数据

93000000(也就是集合竞价)之前的数据,里面有未成交的买单和卖单,每遍历到一个新的[93000000,145700000)之间的订单,就要在之前的未成交的订单里面进行查找相应的数据,并进行处理。
首先将93000000之前的订单进行分类:未成交买单,未成交卖单和已完成订单

# 集合竞价中的数据整理
df_jh = df[df['时间'] < 93000000]
# 集合竞价(93000000之前)未成交买单
df_b_wcj = df_jh[(df_jh['委托类型'] == 'A')&(df_jh['委托代码'] == 'B') & (df_jh['未成交数量'] > 0)]
# 集合竞价(93000000之前)未成交卖单
df_s_wcj = df_jh[(df_jh['委托类型'] == 'A')&(df_jh['委托代码'] == 'S') & (df_jh['未成交数量'] > 0)]
#交易已完成订单(完全撤单和已成交订单)+交易类型为D(撤单类型)的订单
df_ywc = df_jh[(df_jh['未成交数量'] == 0) | (df_jh['委托类型'] == 'D')]

然后开始对[93000000,145700000)的每笔委托单进行遍历数据处理。

for i, row in df_pz.iterrows():

遍历到的订单总共有4种类型:‘委托类型’为A,’委托代码‘为B的是委买订单,AS为委卖订单,DB为撤买订单,DS为撤卖订单。

img

如果遍历到的订单是委买订单(AB),那么需要查找:价格<=该订单’委托价格’的未成交的卖单(<=买价的卖单才能有资格成交)为符合条件的卖单,并且将符合条件的卖单按价格从低到高、交易所委托号从低到高进行排序,排在前面的优先成交。

# 如果遍历到的订单为AB买单
    if (row['委托类型'] == 'A') & (row['委托代码'] == 'B'):  # 遍历到的订单为买单
        # 查找比该买单的委托价格低的未成交的卖单,为符合条件的卖单
        df_s_wcj_match = df_s_wcj[df_s_wcj['委托价格'] <= row['委托价格']]
        # 对符合条件的卖单进行按委托价格和交易所委托号全部升序排序
        df_s_wcj_match_sorted = df_s_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[True, True])

再判断查找到的符合匹配条件的卖单数量是否大于0:
如果等于0,说明前面未成交的卖单里面,没有价格<=AB单委托价格的卖单,即没有符合条件的卖单。这时就将AB单插入到未成交的买单集合里面。

if len(df_s_wcj_match) == 0:  # 没有可成交的订单
            row['未成交数量'] = row['委托数量']  # 未成交数量为委托数量
            # 将该笔买单加入到未成交买单df里面
            df_b_wcj = pd.concat([df_b_wcj, row.to_frame().T], ignore_index=True)
        else:  # 存在可成交的卖单

如果不等于0(只能是大于0),说明前面未成交的卖单里面,存在价格<=AB单委托价格的卖单,即存在符合条件的卖单。

        else:  # 存在可成交的卖单
            num_wcj = 0
            cumulative_sum_vol = 0
            # 对可成交的卖单进行排序后遍历
            for j, r in df_s_wcj_match_sorted.iterrows():

比如遍历到203行时,存在4个符合条件的卖单

img


对这4条卖单进行遍历,并判断累加卖单的未成交数量之和与买单委托数量之和哪个大

遍历第一条卖单:第一条及以前卖单的'未成交数量'之和<买单'委托数量'。
这时候就可以判定,遍历到的第一条卖单全部成交,买单数据部分成交
对遍历到的卖单进行处理:
设置它的成交数量为:原来的成交数量(这里数据有可能不为空)+','+这次的成交数量(即所有的未成交数量1300股全部成交)
设置它的成交时间为:原来的成交时间+','+这次的成交时间(及遍历到的买单的时间)
设置它的未成交数量为:0(这一步卖单全部成交)
将全部成交的卖单放入到已完成的订单集合里面
将全部成交的卖单,从未成交的卖单里面除掉(已经全部成交了)
对买单进行处理:
买单的成交数量就是:第一笔及之前卖单的'未成交数量'之和(cumulative_sum_vol)
买单的成交时间就是它自己的时间
买单的未成交数量是它自己的委托数量减去(第一笔及之前卖单的'未成交数量'之和--cumulative_sum_vol)
再将改买单放到未成交的买单集合里面

# 从遍历到的该笔卖单向前总的未成交卖单数量之和
                cumulative_sum_vol += r['未成交数量']
                # 如果遍历到的该笔卖单之前的总的未成交卖单数量之和小于买单的委托数量:
                if cumulative_sum_vol < row['委托数量']:  # 总的卖单未成交数量小于该行买单委托数量
                    # 卖单全部成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
    
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                    r['未成交数量'] = 0
                    # 将成交完成的卖单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, r.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                    # 将卖单从未成交的卖单集合里面删除
                    df_s_wcj = df_s_wcj[df_s_wcj['交易所委托号'] != r['交易所委托号']]  # 把数据从未成交的卖单里面删除
                    # 遍历到的买单部分成交
                    row['成交数量'] = str(cumulative_sum_vol)
                    row['成交时间'] = row['时间']
                    row['未成交数量'] = row['委托数量'] - cumulative_sum_vol
                    # 将未完全成交的买单放入未成交买单的集合中
                    df_b_wcj = pd.concat([df_b_wcj, row.to_frame().T], ignore_index=True)

处理完的第一条数据

img

继续遍历第二条符合条件的卖单:发现第二条及前面卖单(即第1、2条卖单)的'未成交数量'之和>买单'委托数量'
这时候就可以判定:遍历到的第二条卖单部分成交,买单全部成交
对第二条卖单的处理应该是:
第二笔卖单的'成交数量'为:买单的'委托数量'-(第一单卖单的成交数量),即:第二笔卖单的未成交数量-(两单未成交数量之和-买单委托数量),再加上第二笔卖单原有的'成交数量'。bug就出现在这里!无法赋值成功

img

第二笔卖单的成交时间为:之前的成交时间(可能有多次成交存在)+买单出现的'时间'
第二笔卖单的'未成交数量'为:两笔卖单‘未成交数量’之和减去买单的‘委托数量’
对买单的处理:
买单的'成交数量'=买单的委托数量(买单全部成交)
买单的'成交时间'=买单的'时间'
买单的'未成交数量' = 0
将该买单放入到已完成的订单集合里面
将该买单从未成交的买单集合里面删除

  elif cumulative_sum_vol > row['委托数量']:  # 总的卖单未成交数量大于该行买单委托数量
                     if num_wcj == 0:  # 第一次遍历到大于0
                        # 未成交卖单部分成交
                        r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'] - (cumulative_sum_vol - row['委托数量']))
                        r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                        r['未成交数量'] = cumulative_sum_vol - row['委托数量']
                        # 遍历到的买单全部成交
                        row['成交数量'] = str(row['委托数量'])
                        row['成交时间'] = row['时间']
                        row['未成交数量'] = 0
                        df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != row['交易所委托号']]  # 把row数据从未成交的卖单里面删除
                        df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                        num_wcj += 1

遍历到第三、四条的时候,因为买单已完成,所以不做任何处理

DB和DS委托单需要找到与之相同'交易所委托号'AB/AS订单,用AB/AS的'未成交数量'减去DB/DS的'委托数量':如果差值为0,就表示全部撤单,那么相对应的AB/AS订单'未成交数量'改为0,并放到已完成的订单合集里面,也将DB/DS订单放到已完成的订单里面,方便后面进行输出;如果差值大于0,就表示部分撤单,将AB/AS的'未成交数量'改为原'未成交数量'与DB/DS的'委托数量'的差值,也将DB/DS订单放到已完成的订单里面,方便后面进行输出。

在下面的代码里,第40行的值可以更改成功,第72行的值却更改不成功
文件在网盘[](链接:https://pan.baidu.com/s/1utmUzENRe_N0cGqseo9j-A?pwd=wipw
提取码:wipw

import pandas as pd
import time
pd.set_option('display.max_columns', None)  # 显示所有列
pd.set_option('mode.chained_assignment', None)
df = pd.read_excel(r'E:\BaiduSyncdisk\quant\短线研究\盘口\603767\0616\集合竞价成交未成交处理.xlsx')
df['成交数量'] = df['成交数量'].astype(str)  # 成交数量列改成字符串格式(一笔委托单可能分多次成交,需要插入多次)
# 盘中实时匹配计算
df_pz = df[(df['时间'] >= 93000000) & (df['时间'] < 145700000)]  # 取集合竞价的数据
# 集合竞价中的数据整理
df_jh = df[df['时间'] < 93000000]
# 集合竞价(93000000之前)未成交买单
df_b_wcj = df_jh[(df_jh['委托类型'] == 'A') & (df_jh['委托代码'] == 'B') & (df_jh['未成交数量'] > 0)]
# 集合竞价(93000000之前)未成交卖单
df_s_wcj = df_jh[(df_jh['委托类型'] == 'A') & (df_jh['委托代码'] == 'S') & (df_jh['未成交数量'] > 0)]
# 交易已完成订单(撤单完成和已成交订单)+交易类型为D(撤单类型)的订单
df_ywc = df_jh[(df_jh['未成交数量'] == 0) | (df_jh['委托类型'] == 'D')]

# 对93000000-145700000之间的数据进行遍历处理
for i, row in df_pz.iterrows():
    # 如果遍历到的订单为AB买单
    if (row['委托类型'] == 'A') & (row['委托代码'] == 'B'):  # 遍历到的订单为买单
        # 查找比该买单的委托价格低的未成交的卖单,为符合条件的卖单
        df_s_wcj_match = df_s_wcj[df_s_wcj['委托价格'] <= row['委托价格']]
        # 对符合条件的卖单进行按委托价格和交易所委托号全部升序排序
        df_s_wcj_match_sorted = df_s_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[True, True])
        if len(df_s_wcj_match) == 0:  # 没有可成交的订单
            row['未成交数量'] = row['委托数量']  # 未成交数量为委托数量
            # 将该笔买单加入到未成交买单df里面
            df_b_wcj = pd.concat([df_b_wcj, row.to_frame().T], ignore_index=True)
        else:  # 存在可成交的卖单
            num_wcj = 0
            cumulative_sum_vol = 0
            # 对可成交的卖单进行排序后遍历
            for j, r in df_s_wcj_match_sorted.iterrows():
                # 从遍历到的该笔卖单向前总的未成交卖单数量之和
                cumulative_sum_vol += r['未成交数量']
                # 如果遍历到的该笔卖单之前的总的未成交卖单数量之和小于买单的委托数量:
                if cumulative_sum_vol < row['委托数量']:  # 总的卖单未成交数量小于该行买单委托数量
                    # 卖单全部成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                    # r['成交数量']='00000'
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                    r['未成交数量'] = 0
                    # 将成交完成的卖单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, r.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                    # 将卖单从未成交的卖单集合里面删除
                    df_s_wcj = df_s_wcj[df_s_wcj['交易所委托号'] != r['交易所委托号']]  # 把数据从未成交的卖单里面删除
                    # 遍历到的买单部分成交
                    row['成交数量'] = str(cumulative_sum_vol)
                    row['成交时间'] = row['时间']
                    row['未成交数量'] = row['委托数量'] - cumulative_sum_vol
                    # 将未完全成交的买单放入未成交买单的集合中
                    df_b_wcj = pd.concat([df_b_wcj, row.to_frame().T], ignore_index=True)
                elif cumulative_sum_vol == row['委托数量']:  # 总的卖单未成交数量等于该行买单委托数量
                    # 卖单全部成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                    r['未成交数量'] = 0
                    # 将成交完成的卖单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, r.to_frame().T], ignore_index=True)
                    # 将卖单从未成交的卖单集合里面删除
                    df_s_wcj = df_s_wcj[df_s_wcj['交易所委托号'] != r['交易所委托号']]
                    # 遍历到的买单全部成交
                    row['成交数量'] = str(cumulative_sum_vol)
                    row['成交时间'] = row['时间']
                    row['未成交数量'] = 0
                    # 将成交完成的买单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                elif cumulative_sum_vol > row['委托数量']:  # 总的卖单未成交数量大于该行买单委托数量
                    if num_wcj == 0:  # 第一次遍历到大于0
                        # 未成交卖单部分成交
                        r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'] - (cumulative_sum_vol - row['委托数量']))
                        r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                        r['未成交数量'] = cumulative_sum_vol - row['委托数量']
                        # 遍历到的买单全部成交
                        row['成交数量'] = str(row['委托数量'])
                        row['成交时间'] = row['时间']
                        row['未成交数量'] = 0
                        df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != row['交易所委托号']]  # 把row数据从未成交的卖单里面删除
                        df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                        num_wcj += 1
    elif (row['委托类型'] == 'A') & (row['委托代码'] == 'S'):  # 遍历到的订单为卖单
        # 查找比该卖单的委托价格高的未成交的买单
        df_b_wcj_match = df_b_wcj[df_b_wcj['委托价格'] >= row['委托价格']]
        df_b_wcj_match_sorted = df_b_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[False, True])
        if len(df_b_wcj_match) == 0:  # 没有可成交的买单
            row['未成交数量'] = row['委托数量']  # 未成交数量为委托数量
            # 将该笔卖单加入到未成交卖单df_s_wcj里面
            df_s_wcj = pd.concat([df_s_wcj, row.to_frame().T], ignore_index=True)
        else:  # 存在可成交的买单
            num_wcj = 0
            cumulative_sum_vol = 0
            for j, r in df_b_wcj_match_sorted.iterrows():
                # 从该笔订单向前总的未成交数量之和
                cumulative_sum_vol += r['未成交数量']
                # print(cumulative_sum_vol)
                if cumulative_sum_vol < row['委托数量']:  # 总的卖单未成交数量小于等于该行买单委托数量
                    # 买单全部成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                    r['未成交数量'] = 0
                    # 将成交完成的买单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, r.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                    # 将买单从未成交的买单集合里面删除
                    df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != r['交易所委托号']]  # 把数据从未成交的卖单里面删除
                    # 遍历到的卖单部分成交
                    row['成交数量'] = str(cumulative_sum_vol)
                    row['成交时间'] = row['时间']
                    row['未成交数量'] = row['委托数量'] - cumulative_sum_vol
                    # 将未完全成交的卖单放入未成交买单的集合中
                    df_s_wcj = pd.concat([df_s_wcj, row.to_frame().T], ignore_index=True)
                elif cumulative_sum_vol == row['委托数量']:
                    # 买单全部成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                    r['未成交数量'] = 0
                    # 将成交完成的买单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, r.to_frame().T], ignore_index=True)
                    # 将买单从未成交的买单集合里面删除
                    df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != r['交易所委托号']]
                    # 遍历到的卖单全部成交
                    row['成交数量'] = str(cumulative_sum_vol)
                    row['成交时间'] = row['时间']
                    row['未成交数量'] = 0
                    # 将成交完成的买单放入到已完成的订单集合里面
                    df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                elif cumulative_sum_vol > row['委托数量']:  # 总的卖单未成交数量大于该行买单委托数量
                    if num_wcj == 0:  # 第一次遍历到大于0
                        # 未成交买单部分成交
                        r['成交数量'] = str(r['成交数量']) + ',' + str(
                            r['未成交数量'] - (cumulative_sum_vol - row['委托数量']))
                        r['成交时间'] = str(r['成交时间']) + ',' + str(row['时间'])
                        r['未成交数量'] = cumulative_sum_vol - row['委托数量']
                        # 遍历到的卖单全部成交
                        row['成交数量'] = str(row['委托数量'])
                        row['成交时间'] = row['时间']
                        row['未成交数量'] = 0
                        df_s_wcj = df_s_wcj[df_s_wcj['交易所委托号'] != row['交易所委托号']]  # 把row数据从未成交的卖单里面删除
                        df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                        num_wcj += 1
    # 遍历到的订单未DB撤买
    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'B'):
        wt_num = row['交易所委托号']  # 提取撤单数据的交易所委托号
        wt_num_a_data = df_b_wcj[df_b_wcj['交易所委托号'] == wt_num]  # 找到交易所委托号相同的委托类型为AB的数据
        diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row['委托数量']  # 计算委托数量与撤单数量的差值
        if diff_vol_ad > 0:  # 如果差值大于0,未完全撤单
            print(f'AB委托数量与DB委托数量之差大于0,已完成订单+1,其他不变')
            wt_num_a_data['委托数量'] = diff_vol_ad
            wt_num_a_data['未成交数量'] = diff_vol_ad  # 将差值赋值给委托类型为A,交易所委托号相同数据的委托数量
            wt_num_a_data['撤单数量'] = row['委托数量']  #
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 将委托类型为D的订单,放到已完成的订单里面
        elif diff_vol_ad == 0:
            wt_num_a_data['未成交数量'] = 0
            wt_num_a_data['撤单数量'] = row['委托数量']  #
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)  # 将撤单数据放到已完成订单里面
            df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != wt_num]  # 如果差值等于0,则将wt_num相等的数据从未成交的数据里面删除,放到已完成的数据里面,如下
            df_ywc = pd.concat([df_ywc, wt_num_a_data], ignore_index=True)  # 如果差值等于0,则将该条委托类型为A的数据追加到df_ywc中
    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'S'):
        wt_num_a_data = df_s_wcj[df_s_wcj['交易所委托号'] == row['交易所委托号']]  # 找到交易所委托号相同的委托类型为AS的数据
        diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row['委托数量']  # 计算委托数量与撤单数量的差值
        # print(diff_vol_ad)
        if diff_vol_ad > 0:  # 如果差值大于0
            wt_num_a_data['委托数量'] = diff_vol_ad
            wt_num_a_data['未成交数量'] = diff_vol_ad  # 将差值赋值给委托类型为A,交易所委托号相同数据的委托数量
            wt_num_a_data['撤单数量'] = row['委托数量']  #
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)
        elif diff_vol_ad == 0:
            wt_num_a_data['未成交数量'] = 0
            wt_num_a_data['撤单数量'] = row['委托数量']  #
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)
            df_s_wcj = df_s_wcj[
                df_s_wcj['交易所委托号'] != row['交易所委托号']]  # 如果差值等于0,则将wt_num相等的数据从未成交的数据里面删除,放到已完成的数据里面,如下
            df_ywc = pd.concat([df_ywc, wt_num_a_data], ignore_index=True)  # 如果差值等于0,则将该条委托类型为A的数据追加到df_ywc中
    if i == 203:
        break
# 合并未成交买单、未成交卖单及已完成订单
merged_df = pd.concat([df_s_wcj, df_b_wcj, df_ywc])
merged_df = merged_df.sort_values(by=['时间', '交易所委托号'], ascending=[True, True])
merged_df = merged_df.reset_index(drop=True)
merged_df.to_excel(r'E:\BaiduSyncdisk\quant\短线研究\盘口\603767\0616\盘中实时成交未成交处理2.xlsx', index=False)

你是不是描述一下你想实现啥会更好些

你是如何判断第73行的值更改不成功的, 请描述一下正确的结果应该是什么样的

请描述一下想要实现怎么样的逻辑思路

值更改不成功是什么样的?保持了原值还是被改成其他数值了?

描述下需求

一个是df_s_wcj,一个是df_b_wcj,你看下

41行的代码和73行的代码在同一套逻辑中,如果执行了41行的代码,则73行代码不会执行。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/1089095
  • 以下回答由chatgpt基于相关博客总结生成:

    我可以尝试回答关于IT方面的问题,请问您有什么具体的问题需要我解答吗?


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

你可以尝试先描述一下需求,再解释步骤,看起来应该会更清晰一些。

请检查下第71行执行不成功前面的if num_wcj == 0:条件语句是否正常执行,如果没有执行,就会导致后面的代码无法赋值。其次,可以将71行赋值不成功的地方的变量的值输出以下看,数据的值是否是正确的。再就是看下是否在这里已经赋值成功了,但是在其他地方的代码把这个值给覆盖调了

用python的 pandas 处理

试试FME,处理数据简单又强大

这100块,不好挣。。

采用chatgpt:
根据提供的代码,问题似乎在于您尝试修改循环中行的 DataFrame 值的方式。 当您使用 row['column'] = new_value 直接修改循环中的行值时,它不会更新原始 DataFrame,而只会更新 DataFrame 中的行的副本。

为了确保更改应用于原始 DataFrame,您应该使用 .loc 根据行索引设置值。 以下是修改循环以正确更新值的方法:

# ... (previous code)

# 对93000000-145700000之间的数据进行遍历处理
for i, row in df_pz.iterrows():
    if i == 204:
        break
    # 如果遍历到的订单为AB买单
    if (row['委托类型'] == 'A') & (row['委托代码'] == 'B'):
        # ...
        # Your existing code for handling buy orders
        # ...
    # 遍历到的订单未DB撤买
    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'B'):
        wt_num = row['交易所委托号']
        wt_num_a_data = df_b_wcj[df_b_wcj['交易所委托号'] == wt_num]
        diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row['委托数量']
        if diff_vol_ad > 0:
            wt_num_a_data.loc[wt_num_a_data.index[0], '委托数量'] = diff_vol_ad
            wt_num_a_data.loc[wt_num_a_data.index[0], '未成交数量'] = diff_vol_ad
            wt_num_a_data.loc[wt_num_a_data.index[0], '撤单数量'] = row['委托数量']
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)
        elif diff_vol_ad == 0:
            wt_num_a_data.loc[wt_num_a_data.index[0], '未成交数量'] = 0
            wt_num_a_data.loc[wt_num_a_data.index[0], '撤单数量'] = row['委托数量']
            df_ywc = pd.concat([df_ywc, row.to_frame().T], ignore_index=True)
            df_b_wcj = df_b_wcj[df_b_wcj['交易所委托号'] != wt_num]
            df_ywc = pd.concat([df_ywc, wt_num_a_data], ignore_index=True)
    # 遍历到的订单未DS撤卖
    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'S'):
        wt_num_a_data = df_s_wcj[df_s_wcj['交易所委托号'] == row['交易所委托号']]
        diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row['委托数量']
        # ...
        # Your existing code for handling sell orders
        # ...
        
# ... (the rest of your code)

通过将 .loc 与行索引一起使用,您将更新原始 DataFrame,并且更改应反映在 df_b_wcj 和 df_s_wcj 中。

因为你用的是混合赋值操作

类似这样df['成交数量'] = df['成交数量'].astype(str)

这个会导致Pandas原始数据帧df和子数据帧存在引用关系

你要用copy()的方法来创建帧副本


# 对93000000-145700000之间的数据进行遍历处理
for i, row in df_pz.iterrows():
    if i == 204:
        break
    # 如果遍历到的订单为AB买单
    if (row['委托类型'] == 'A') & (row['委托代码'] == 'B'):  # 遍历到的订单为买单
        # 查找比该买单的委托价格低的未成交的卖单,为符合条件的卖单
        df_s_wcj_match = df_s_wcj[df_s_wcj['委托价格'] <= row['委托价格']]
        # 对符合条件的卖单进行按委托价格和交易所委托号全部升序排序
        df_s_wcj_match_sorted = df_s_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[True, True]).copy()  # 使用copy()创建副本
        # 其他代码不变...
    elif (row['委托类型'] == 'A') & (row['委托代码'] == 'S'):  # 遍历到的订单为卖单
        # 查找比该卖单的委托价格高的未成交的买单
        df_b_wcj_match = df_b_wcj[df_b_wcj['委托价格'] >= row['委托价格']]
        df_b_wcj_match_sorted = df_b_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[False, True]).copy()  # 使用copy()创建副本
        # 其他代码不变...

类似这样改

对于股票交易委托数据表,您想对时间处于[93000000,145700000)范围内的每笔委托单进行数据处理。是的,可以使用 Python 的 pandas 库进行数据处理。您可以使用以下代码实现该功能
引用了c知道,

import pandas as pd

# 读取委托数据表
df = pd.read_csv('委托数据.csv')

# 将时间列转换为数值型
df['时间'] = pd.to_numeric(df['时间'], errors='coerce')

# 过滤时间范围内的委托单
filtered_df = df[(df['时间'] >= 93000000) & (df['时间'] < 145700000)]

# 在这里进行您想要的数据处理操作,例如计算均值、筛选特定条件等

# 输出处理后的结果
print(filtered_df)

请将代码中的 '委托数据.csv' 替换为您实际的委托数据文件名或路径。然后,您可以根据需要在注释标记的位置进行数据处理操作。最后,通过 print(filtered_df) 来输出处理后的结果。

Pandas 是 Python 中的一个数据处理库,它提供了大量的工具和函数,可以帮助我们方便地进行数据分析和处理。Pandas 主要提供了两个数据类型:Series 和 DataFrame,前者是一维数组,后者是二维表格。

Pandas 主要的数据处理功能包括:

  1. 数据读取:Pandas 可以读取多种数据格式,例如 CSV、Excel、SQL 数据库等。读取数据后,Pandas 将其转换为 DataFrame 格式,方便我们进行分析和处理。

  2. 数据清洗:在进行数据分析和处理之前,需要对数据进行清洗,例如处理缺失值、异常值、重复值等。Pandas 提供了一系列函数来处理这些问题,例如 dropna()、fillna()、drop_duplicates() 等。

  3. 数据处理:Pandas 提供了一系列函数来进行数据处理,例如排序、数据合并、重塑、分组聚合等。这些函数可以帮助我们快速地对数据进行处理,提高数据分析的效率。

  4. 数据可视化:Pandas 也支持数据可视化功能,它可以帮助我们直观地展现数据分析的结果,更容易地理解数据的含义。Pandas 支持多种图表类型,例如折线图、散点图、柱状图等。

下面以一个具体的例子来介绍 Pandas 的数据处理功能。

假设我们想要分析一份银行客户的数据,数据包含客户的姓名、年龄、性别、婚姻状况、收入、贷款金额等信息。数据存储在一个 CSV 文件中,我们可以使用 Pandas 的 read_csv() 函数将其读取到 DataFrame 中:

import pandas as pd

df = pd.read_csv('bank_customer.csv')

读取数据后,我们可以使用 head() 函数查看前几行数据:

df.head()

输出结果:

   Name  Age Gender  Marital Status  Income  Loan Amount
0  John   30      M        Married   50000        10000
1  Jane   25      F         Single   40000         5000
2  Jack   35      M         Single   60000        15000
3  Anne   28      F        Married   55000        12000
4  Eric   32      M        Married   70000        20000

我们可以看到,数据包含 6 列,分别是姓名、年龄、性别、婚姻状况、收入和贷款金额。接下来,我们可以对数据进行清洗和处理。

首先,我们可以检查数据中是否存在缺失值:

df.isnull().sum()

输出结果:

Name             0
Age              0
Gender           0
Marital Status   0
Income           2
Loan Amount      1
dtype: int64

我们可以看到,数据中有两列存在缺失值,分别是收入和贷款金额。我们可以使用 fillna() 函数将缺失值填充为平均值:

df.fillna(df.mean(), inplace=True)

然后,我们可以对数据进行排序,例如按照收入从高到低排序:

df.sort_values('Income', ascending=False, inplace=True)

接下来,我们可以对数据进行分组聚合,例如按照婚姻状况计算平均收入和平均贷款金额:

df_grouped = df.groupby('Marital Status').agg({'Income': 'mean', 'Loan Amount': 'mean'})
print(df_grouped)

输出结果:

                     Income  Loan Amount
Marital Status                          
Married         61666.666667     14000.00
Single          46666.666667      8333.33

我们可以看到,已婚客户的平均收入和平均贷款金额都高于单身客户。最后,我们可以将数据可视化,例如绘制收入和贷款金额的散点图:

import matplotlib.pyplot as plt

plt.scatter(df['Income'], df['Loan Amount'])
plt.xlabel('Income')
plt.ylabel('Loan Amount')
plt.show()

输出结果:

scatter plot

综上所述,Pandas 提供了丰富的数据处理功能,可以帮助我们方便地进行数据分析和处理,提高数据分析的效率和准确性。

问题点:业务存在复杂度. 计算过程涉及到中间变量的更新
思路分析: ①对各类处理的方法做一层封装, 这样,变量的流转将会清晰很多 ②补全代码, 增加else,明确打印未执行的情况.
代码修改如下:

import pandas as pd

pd.set_option('display.max_columns', None)  # 显示所有列
pd.set_option('mode.chained_assignment', None)
df = pd.read_excel(r'E:\BaiduSyncdisk\quant\短线研究\盘口\603767\0616\集合竞价成交未成交处理.xlsx')
df['成交数量'] = df['成交数量'].astype(str)  # 成交数量列改成字符串格式(一笔委托单可能分多次成交,需要插入多次)
# 盘中实时匹配计算
df_pz = df[(df['时间'] >= 93000000) & (df['时间'] < 145700000)]  # 取集合竞价的数据
# 集合竞价中的数据整理
df_jh = df[df['时间'] < 93000000]
# 集合竞价(93000000之前)未成交买单
df_b_wcj = df_jh[(df_jh['委托类型'] == 'A') & (df_jh['委托代码'] == 'B') & (df_jh['未成交数量'] > 0)]
# 集合竞价(93000000之前)未成交卖单
df_s_wcj = df_jh[(df_jh['委托类型'] == 'A') & (df_jh['委托代码'] == 'S') & (df_jh['未成交数量'] > 0)]
# 交易已完成订单(撤单完成和已成交订单)+交易类型为D(撤单类型)的订单
df_ywc = df_jh[(df_jh['未成交数量'] == 0) | (df_jh['委托类型'] == 'D')]


# AB买单   查找比该买单的委托价格低的未成交的卖单,为符合条件的卖单
def func_A_B(row_data, _df_s_wcj, _df_b_wcj, _df_ywc):
    # 查找比该买单的委托价格低的未成交的卖单,为符合条件的卖单
    _df_s_wcj_match = _df_s_wcj[_df_s_wcj['委托价格'] <= row_data['委托价格']]
    if len(_df_s_wcj_match) == 0:  # 没有可成交的订单
        row_data['未成交数量'] = row_data['委托数量']  # 未成交数量为委托数量
        # 将该笔买单加入到未成交买单df里面
        _df_b_wcj = pd.concat([_df_b_wcj, row_data.to_frame().T], ignore_index=True)
    else:  # 存在可成交的卖单
        num_wcj = 0
        cumulative_sum_vol = 0
        # 对符合条件的卖单进行按委托价格和交易所委托号全部升序排序
        _df_s_wcj_match_sorted = _df_s_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[True, True])
        # 对可成交的卖单进行排序后遍历
        for j, r in _df_s_wcj_match_sorted.iterrow_datas():
            # 从遍历到的该笔卖单向前总的未成交卖单数量之和
            cumulative_sum_vol += r['未成交数量']
            # 如果遍历到的该笔卖单之前的总的未成交卖单数量之和小于买单的委托数量:
            if cumulative_sum_vol < row_data['委托数量']:  # 总的卖单未成交数量小于该行买单委托数量
                # 卖单全部成交
                r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                # r['成交数量']='00000'
                r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                r['未成交数量'] = 0
                # 将成交完成的卖单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, r.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                # 将卖单从未成交的卖单集合里面删除
                _df_s_wcj = _df_s_wcj[_df_s_wcj['交易所委托号'] != r['交易所委托号']]  # 把数据从未成交的卖单里面删除
                # 遍历到的买单部分成交
                row_data['成交数量'] = str(cumulative_sum_vol)
                row_data['成交时间'] = row_data['时间']
                row_data['未成交数量'] = row_data['委托数量'] - cumulative_sum_vol
                # 将未完全成交的买单放入未成交买单的集合中
                _df_b_wcj = pd.concat([_df_b_wcj, row_data.to_frame().T], ignore_index=True)
            elif cumulative_sum_vol == row_data['委托数量']:  # 总的卖单未成交数量等于该行买单委托数量
                # 卖单全部成交
                r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                r['未成交数量'] = 0
                # 将成交完成的卖单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, r.to_frame().T], ignore_index=True)
                # 将卖单从未成交的卖单集合里面删除
                _df_s_wcj = _df_s_wcj[_df_s_wcj['交易所委托号'] != r['交易所委托号']]
                # 遍历到的买单全部成交
                row_data['成交数量'] = str(cumulative_sum_vol)
                row_data['成交时间'] = row_data['时间']
                row_data['未成交数量'] = 0
                # 将成交完成的买单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
            elif cumulative_sum_vol > row_data['委托数量']:  # 总的卖单未成交数量大于该行买单委托数量
                if num_wcj == 0:  # 第一次遍历到大于0
                    # 未成交卖单部分成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'] - (cumulative_sum_vol - row_data['委托数量']))
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                    r['未成交数量'] = cumulative_sum_vol - row_data['委托数量']
                    # 遍历到的买单全部成交
                    row_data['成交数量'] = str(row_data['委托数量'])
                    row_data['成交时间'] = row_data['时间']
                    row_data['未成交数量'] = 0
                    _df_b_wcj = _df_b_wcj[_df_b_wcj['交易所委托号'] != row_data['交易所委托号']]  # 把row_data数据从未成交的卖单里面删除
                    _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                    num_wcj += 1
            else:
                print(f'func_A_B未执行 {j}')
    return _df_s_wcj, _df_b_wcj, _df_ywc


def func_A_S(row_data, _df_b_wcj, _df_s_wcj, _df_ywc):
    # 查找比该卖单的委托价格高的未成交的买单
    _df_b_wcj_match = _df_b_wcj[_df_b_wcj['委托价格'] >= row_data['委托价格']]
    _df_b_wcj_match_sorted = _df_b_wcj_match.sort_values(by=['委托价格', '交易所委托号'], ascending=[False, True])
    if len(_df_b_wcj_match) == 0:  # 没有可成交的买单
        row_data['未成交数量'] = row_data['委托数量']  # 未成交数量为委托数量
        # 将该笔卖单加入到未成交卖单_df_s_wcj里面
        _df_s_wcj = pd.concat([_df_s_wcj, row_data.to_frame().T], ignore_index=True)
    else:  # 存在可成交的买单
        num_wcj = 0
        cumulative_sum_vol = 0
        for j, r in _df_b_wcj_match_sorted.iterrow_datas():
            # 从该笔订单向前总的未成交数量之和
            cumulative_sum_vol += r['未成交数量']
            # print(cumulative_sum_vol)
            if cumulative_sum_vol < row_data['委托数量']:  # 总的卖单未成交数量小于等于该行买单委托数量
                # 买单全部成交
                r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                r['未成交数量'] = 0
                # 将成交完成的买单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, r.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                # 将买单从未成交的买单集合里面删除
                _df_b_wcj = _df_b_wcj[_df_b_wcj['交易所委托号'] != r['交易所委托号']]  # 把数据从未成交的卖单里面删除
                # 遍历到的卖单部分成交
                row_data['成交数量'] = str(cumulative_sum_vol)
                row_data['成交时间'] = row_data['时间']
                row_data['未成交数量'] = row_data['委托数量'] - cumulative_sum_vol
                # 将未完全成交的卖单放入未成交买单的集合中
                _df_s_wcj = pd.concat([_df_s_wcj, row_data.to_frame().T], ignore_index=True)
            elif cumulative_sum_vol == row_data['委托数量']:
                # 买单全部成交
                r['成交数量'] = str(r['成交数量']) + ',' + str(r['未成交数量'])
                r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                r['未成交数量'] = 0
                # 将成交完成的买单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, r.to_frame().T], ignore_index=True)
                # 将买单从未成交的买单集合里面删除
                _df_b_wcj = _df_b_wcj[_df_b_wcj['交易所委托号'] != r['交易所委托号']]
                # 遍历到的卖单全部成交
                row_data['成交数量'] = str(cumulative_sum_vol)
                row_data['成交时间'] = row_data['时间']
                row_data['未成交数量'] = 0
                # 将成交完成的买单放入到已完成的订单集合里面
                _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
            elif cumulative_sum_vol > row_data['委托数量']:  # 总的卖单未成交数量大于该行买单委托数量
                if num_wcj == 0:  # 第一次遍历到大于0
                    # 未成交买单部分成交
                    r['成交数量'] = str(r['成交数量']) + ',' + str(
                        r['未成交数量'] - (cumulative_sum_vol - row_data['委托数量']))
                    r['成交时间'] = str(r['成交时间']) + ',' + str(row_data['时间'])
                    r['未成交数量'] = cumulative_sum_vol - row_data['委托数量']
                    # 遍历到的卖单全部成交
                    row_data['成交数量'] = str(row_data['委托数量'])
                    row_data['成交时间'] = row_data['时间']
                    row_data['未成交数量'] = 0
                    _df_s_wcj = _df_s_wcj[_df_s_wcj['交易所委托号'] != row_data['交易所委托号']]  # 把row_data数据从未成交的卖单里面删除
                    _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 把数据加入到已完成的订单里面
                    num_wcj += 1
            else:
                print(f'func_A_S 未执行 {j}')
    return _df_b_wcj, _df_s_wcj, _df_ywc


def func_B_D(row_data, _df_b_wcj, _df_ywc):
    wt_num = row_data['交易所委托号']  # 提取撤单数据的交易所委托号
    wt_num_a_data = _df_b_wcj[_df_b_wcj['交易所委托号'] == wt_num]  # 找到交易所委托号相同的委托类型为AB的数据
    diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row_data['委托数量']  # 计算委托数量与撤单数量的差值
    if diff_vol_ad > 0:  # 如果差值大于0,未完全撤单
        print(f'AB委托数量与DB委托数量之差大于0,已完成订单+1,其他不变')
        wt_num_a_data['委托数量'] = diff_vol_ad
        wt_num_a_data['未成交数量'] = diff_vol_ad  # 将差值赋值给委托类型为A,交易所委托号相同数据的委托数量
        wt_num_a_data['撤单数量'] = row_data['委托数量']  #
        _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 将委托类型为D的订单,放到已完成的订单里面
    elif diff_vol_ad == 0:
        wt_num_a_data['未成交数量'] = 0
        wt_num_a_data['撤单数量'] = row_data['委托数量']  #
        _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)  # 将撤单数据放到已完成订单里面
        _df_b_wcj = _df_b_wcj[_df_b_wcj['交易所委托号'] != wt_num]  # 如果差值等于0,则将wt_num相等的数据从未成交的数据里面删除,放到已完成的数据里面,如下
        _df_ywc = pd.concat([_df_ywc, wt_num_a_data], ignore_index=True)  # 如果差值等于0,则将该条委托类型为A的数据追加到_df_ywc中
    else:
        print(f'func_B_D 未执行 diff_vol_ad={diff_vol_ad}')
    return _df_b_wcj, _df_ywc


def func_D_S(row_data, _df_s_wcj, _df_ywc):
    wt_num = row_data['交易所委托号']  # 提取撤单数据的交易所委托号
    wt_num_a_data = _df_s_wcj[_df_s_wcj['交易所委托号'] == wt_num]  # 找到交易所委托号相同的委托类型为AS的数据
    diff_vol_ad = wt_num_a_data['委托数量'].values[0] - row_data['委托数量']  # 计算委托数量与撤单数量的差值
    # print(diff_vol_ad)
    if diff_vol_ad > 0:  # 如果差值大于0
        wt_num_a_data['委托数量'] = diff_vol_ad
        wt_num_a_data['未成交数量'] = diff_vol_ad  # 将差值赋值给委托类型为A,交易所委托号相同数据的委托数量
        wt_num_a_data['撤单数量'] = row_data['委托数量']  #
        _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)
    elif diff_vol_ad == 0:
        wt_num_a_data['未成交数量'] = 0
        wt_num_a_data['撤单数量'] = row_data['委托数量']  #
        _df_ywc = pd.concat([_df_ywc, row_data.to_frame().T], ignore_index=True)
        _df_s_wcj = _df_s_wcj[
            _df_s_wcj['交易所委托号'] != wt_num]  # 如果差值等于0,则将wt_num相等的数据从未成交的数据里面删除,放到已完成的数据里面,如下
        _df_ywc = pd.concat([_df_ywc, wt_num_a_data], ignore_index=True)  # 如果差值等于0,则将该条委托类型为A的数据追加到_df_ywc中
    else:
        print(f'func_D_S 未执行 diff_vol_ad={diff_vol_ad}')
    return _df_s_wcj, _df_ywc


# 对93000000-145700000之间的数据进行遍历处理
for i, row in df_pz.iterrows():
    if i > 203:
        break

    # 如果遍历到的订单为AB买单
    if (row['委托类型'] == 'A') & (row['委托代码'] == 'B'):  # 遍历到的订单为买单
        df_s_wcj, df_b_wcj, df_ywc = func_A_B(row, df_s_wcj, df_b_wcj, df_ywc)

    elif (row['委托类型'] == 'A') & (row['委托代码'] == 'S'):  # 遍历到的订单为卖单
        df_s_wcj, df_b_wcj, df_ywc = func_A_S(row, df_s_wcj, df_b_wcj, df_ywc)
    # 遍历到的订单未DB撤买
    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'B'):
        df_b_wcj, df_ywc = func_B_D(row, df_b_wcj, df_ywc)

    elif (row['委托类型'] == 'D') & (row['委托代码'] == 'S'):
        df_s_wcj, df_ywc = func_D_S(row, df_s_wcj, df_ywc)

# 合并未成交买单、未成交卖单及已完成订单
merged_df = pd.concat([df_s_wcj, df_b_wcj, df_ywc])
merged_df = merged_df.sort_values(by=['时间', '交易所委托号'], ascending=[True, True])
merged_df = merged_df.reset_index(drop=True)
merged_df.to_excel(r'E:\BaiduSyncdisk\quant\短线研究\盘口\603767\0616\盘中实时成交未成交处理2.xlsx', index=False)