Python 如何不将值设置为副本的切片

Python 如何不将值设置为副本的切片,python,pandas,Python,Pandas,我试图在不创建副本的情况下替换列中的字符串值。我已经查看了警告中提供的信息以及此信息。我也尝试过使用.replace(),结果相同。我不明白什么? 代码: 希望这能满足复制所需的数据: ,Date,Type,Action,Symbol,Instrument Type,Description,Value,Quantity,Average Price,Commissions,Fees,Multiplier,Underlying Symbol,Expiration Date,Strike Price,

我试图在不创建副本的情况下替换列中的字符串值。我已经查看了警告中提供的信息以及此信息。我也尝试过使用
.replace()
,结果相同。我不明白什么? 代码:

希望这能满足复制所需的数据:

,Date,Type,Action,Symbol,Instrument Type,Description,Value,Quantity,Average Price,Commissions,Fees,Multiplier,Underlying Symbol,Expiration Date,Strike Price,Call or Put
36,2019-12-31 16:01:44,Trade,BUY_TO_OPEN,QQQ   200103P00206500,Equity Option,Bought 1 QQQ 01/03/20 Put 206.50 @ 0.07,-7,1,-7,-1.0,-0.14,100.0,QQQ,1/3/2020,206.5,PUT
37,2019-12-31 16:01:44,Trade,BUY_TO_OPEN,QQQ   200103C00217500,Equity Option,Bought 1 QQQ 01/03/20 Call 217.50 @ 0.03,-3,1,-3,-1.0,-0.14,100.0,QQQ,1/3/2020,217.5,CALL
38,2019-12-31 16:01:44,Trade,SELL_TO_OPEN,QQQ   200103P00209000,Equity Option,Sold 1 QQQ 01/03/20 Put 209.00 @ 0.14,14,1,14,-1.0,-0.15,100.0,QQQ,1/3/2020,209.0,PUT
39,2019-12-31 16:01:44,Trade,SELL_TO_OPEN,QQQ   200103C00214500,Equity Option,Sold 1 QQQ 01/03/20 Call 214.50 @ 0.30,30,1,30,-1.0,-0.15,100.0,QQQ,1/3/2020,214.5,CALL
40,2020-01-03 16:08:13,Trade,BUY_TO_CLOSE,QQQ   200103C00214500,Equity Option,Bought 1 QQQ 01/03/20 Call 214.50 @ 0.07,-7,1,-7,0.0,-0.14,100.0,QQQ,1/3/2020,214.5,CALL
预期结果:

,Date,Type,Action,Symbol,Instrument Type,Description,Value,Quantity,Average Price,Commissions,Fees,Multiplier,Underlying Symbol,Expiration Date,Strike Price,Call or Put
36,2019-12-31 16:01:44,Trade,BUY_TO_OPEN,QQQ   200103P00206500,Equity Option,Bought 1 QQQ 01/03/20 Put 206.50 @ 0.07,-7,1,-7,-1.0,-0.14,100.0,QQQ,1/3/2020,206.5,PUT,Iron Condor
37,2019-12-31 16:01:44,Trade,BUY_TO_OPEN,QQQ   200103C00217500,Equity Option,Bought 1 QQQ 01/03/20 Call 217.50 @ 0.03,-3,1,-3,-1.0,-0.14,100.0,QQQ,1/3/2020,217.5,CALL,Iron Condor
38,2019-12-31 16:01:44,Trade,SELL_TO_OPEN,QQQ   200103P00209000,Equity Option,Sold 1 QQQ 01/03/20 Put 209.00 @ 0.14,14,1,14,-1.0,-0.15,100.0,QQQ,1/3/2020,209.0,PUT,Iron Condor
39,2019-12-31 16:01:44,Trade,SELL_TO_OPEN,QQQ   200103C00214500,Equity Option,Sold 1 QQQ 01/03/20 Call 214.50 @ 0.30,30,1,30,-1.0,-0.15,100.0,QQQ,1/3/2020,214.5,CALL,Iron Condor
40,2020-01-03 16:08:13,Trade,BUY_TO_CLOSE,QQQ   200103C00214500,Equity Option,Bought 1 QQQ 01/03/20 Call 214.50 @ 0.07,-7,1,-7,0.0,-0.14,100.0,QQQ,1/3/2020,214.5,CALL,

这里有一篇非常详细的帖子,不仅可以回答你的问题,还可以详细解释事情的原因


简而言之,如果你想设置原始df的值,可以使用
.replace(inplace=True)
df.loc[condition,theColtoBeSet]=new\u val

这是一篇非常详细的文章,它不仅可以回答你的问题,还可以详细解释为什么会出现这种情况


简而言之,如果要设置原始df的值,请使用
.replace(inplace=True)
df.loc[condition,theColtoBeSet]=new\u val

让我们从代码初始部分的一些改进开始:

  • 输入文件最左边的列显然是索引列, 所以应该把它读作索引。结果是采取了一些不同的方法 访问行的方式(稍后详细信息)

  • 日期列最早可以在读取时转换为datetime64

  • 因此,代码的初始部分可以是:

    TRADER_READER = pd.read_csv('Input.csv', index_col=0, parse_dates=['Date'])
    TRADER_READER['Strategy'] = ''
    
    然后我决定以另一种方式组织循环:

  • indStart是索引列的整数索引

  • 当您以4个连续行的“重叠”对处理文件时, 组织循环的一种更自然的方法是从末尾开始在第4行停止。 因此循环超出了范围(TRADER_READER.index.size-3)

  • 可以从数据库的相应切片中读取4行感兴趣的索引 索引,即[indStart:indStart+4]

  • 可以使用嵌套函数执行特定行的检查

  • 为避免警告,策略列中的值设置应为 在原始数据帧上使用loc执行,行参数为 策略的相应行和列参数

  • 整个更新(对于当前的4行)可以在中执行 一条单指令,将行参数指定为, 从a到d

  • 因此,代码可以如下所示:

    def iron_condor():
        def rowCheck(row):
            return start_time <= row.Date <= end_time and row['Underlying Symbol'] == undSymb
    
        for indStart in range(TRADER_READER.index.size - 3):
            a, b, c, d = TRADER_READER.index[indStart : indStart + 4]
            e = TRADER_READER.loc[a]
            undSymb = e['Underlying Symbol']
            start_time = e.Date
            end_time = start_time + pd.Timedelta('5S')
            if rowCheck(TRADER_READER.loc[b]) and rowCheck(TRADER_READER.loc[c]) and rowCheck(TRADER_READER.loc[d]):
                TRADER_READER.loc[a:d, 'Strategy'] = 'Iron Condor'
                print('New values:')
                print(TRADER_READER.loc[a:d])
    
    但实际上你不需要这么做。检查是否 已找到匹配项,因此条件可能为:

    found = bool(re.search('.*TO_OPEN$', row['Action']))
    
    (注意,None cast to bool返回False和任何非Null对象 返回True)

    另一个(可能更简单、更快)解决方案是,您只需运行:

    row.Action.endswith('TO_OPEN')
    

    不调用任何正则表达式函数。

    让我们从代码初始部分的一些改进开始:

  • 输入文件最左边的列显然是索引列, 所以应该把它读作索引。结果是采取了一些不同的方法 访问行的方式(稍后详细信息)

  • 日期列最早可以在读取时转换为datetime64

  • 因此,代码的初始部分可以是:

    TRADER_READER = pd.read_csv('Input.csv', index_col=0, parse_dates=['Date'])
    TRADER_READER['Strategy'] = ''
    
    然后我决定以另一种方式组织循环:

  • indStart是索引列的整数索引

  • 当您以4个连续行的“重叠”对处理文件时, 组织循环的一种更自然的方法是从末尾开始在第4行停止。 因此循环超出了范围(TRADER_READER.index.size-3)

  • 可以从数据库的相应切片中读取4行感兴趣的索引 索引,即[indStart:indStart+4]

  • 可以使用嵌套函数执行特定行的检查

  • 为避免警告,策略列中的值设置应为 在原始数据帧上使用loc执行,行参数为 策略的相应行和列参数

  • 整个更新(对于当前的4行)可以在中执行 一条单指令,将行参数指定为, 从a到d

  • 因此,代码可以如下所示:

    def iron_condor():
        def rowCheck(row):
            return start_time <= row.Date <= end_time and row['Underlying Symbol'] == undSymb
    
        for indStart in range(TRADER_READER.index.size - 3):
            a, b, c, d = TRADER_READER.index[indStart : indStart + 4]
            e = TRADER_READER.loc[a]
            undSymb = e['Underlying Symbol']
            start_time = e.Date
            end_time = start_time + pd.Timedelta('5S')
            if rowCheck(TRADER_READER.loc[b]) and rowCheck(TRADER_READER.loc[c]) and rowCheck(TRADER_READER.loc[d]):
                TRADER_READER.loc[a:d, 'Strategy'] = 'Iron Condor'
                print('New values:')
                print(TRADER_READER.loc[a:d])
    
    但实际上你不需要这么做。检查是否 已找到匹配项,因此条件可能为:

    found = bool(re.search('.*TO_OPEN$', row['Action']))
    
    (注意,None cast to bool返回False和任何非Null对象 返回True)

    另一个(可能更简单、更快)解决方案是,您只需运行:

    row.Action.endswith('TO_OPEN')
    

    不调用任何正则表达式函数。

    查找最小示例。您的代码无法复制,因为人们没有您正在阅读的电子表格。此外,您的代码包含不必要的行以理解可能出现的错误。请提供一段基础数据和预期结果。乍一看,这是一个奇怪的组合,您有一个以row作为控制变量的循环,但从未使用过它。另一个重要的遗漏细节是:您的代码中哪一行导致了您提出的警告?我提供了更多的数据,我已经提供了警告的全部内容。如果你想的话,我会拍一张截图来证明这一点。我之所以使用
    row
    是因为它可以工作。我认为问题出在
    e=TRADER\u READER.iloc[a]
    中,请按照dupe by
    e=TRADER\u READER.iloc[a].copy()
    中提到的那样更改它,类似于
    f,g,h
    这并没有给出错误,但它并没有替换值。请查找最简单的示例。您的代码无法复制,因为人们没有您正在阅读的电子表格。此外,您的代码包含不必要的行以理解可能出现的错误。请提供一段基础数据和预期结果。乍一看,这是一个奇怪的组合,您有一个以row作为控制变量的循环,但从未使用过它。另一个重要的缺失细节是:代码的哪一行导致警告