python - 如何有效地净化pandas数据框?

标签 python pandas

我很难用正确的词语写出我的问题,所以感谢您阅读我的问题。

我有一个数据框,它有两列,high , low ,其中记录了 较高值和较低值。

例如:

     high   low
0     NaN   NaN
1   100.0   NaN
2     NaN  50.0
3   110.0   NaN
4     NaN   NaN
5   120.0   NaN
6   100.0   NaN
7     NaN   NaN
8     NaN  30.0
9     NaN   NaN
10    NaN  20.0
11    NaN   NaN
12  110.0   NaN
13    NaN   NaN

我想合并连续的(在同一侧),并保留最高(最低)的。

“连续的”是指 high 中的值low 中两个值之间的列列,或 low 中的值high 中两个值之间的列栏目

索引 3 上的高值, 5 , 6应该合并,索引 5 上的最高值(值 120 )应保留。

索引 8 的低值, 10应该合并,索引 10 上的最低值(值 20 )应保留。

结果是这样的:

     high   low
0     NaN   NaN
1   100.0   NaN
2     NaN  50.0
3     NaN   NaN
4     NaN   NaN
5   120.0   NaN
6     NaN   NaN
7     NaN   NaN
8     NaN   NaN
9     NaN   NaN
10    NaN  20.0
11    NaN   NaN
12  110.0   NaN
13    NaN   NaN

我尝试编写一个for循环来处理数据,但是当数据很大(超过10,000)时,它非常慢。

代码是:

import pandas as pd

data=pd.DataFrame(dict(high=[None,100,None,110,None,120,100,None,None,None,None,None,110,None],
                    low=[None,None,50,None,None,None,None,None,30,None,20,None,None,None]))
flag = None
flag_index = None
for i in range(len(data)):
    if not pd.isna(data['high'][i]):
        if flag == 'flag_high':
            higher = data['high'].iloc[[i, flag_index]].idxmax()
            lower = flag_index if i == higher else i
            flag_index = higher
            data['high'][lower] = None
        else:
            flag = 'flag_high'
            flag_index = i
    elif not pd.isna(data['low'][i]):
        if flag == 'flag_low':
            lower = data['low'].iloc[[i, flag_index]].idxmin()
            higher = flag_index if i == lower else i
            flag_index = lower
            data['low'][higher] = None
        else:
            flag = 'flag_low'
            flag_index = i

有什么有效的方法可以做到这一点吗?

谢谢

最佳答案

对于像这样的面向行的迭代处理,pandas 通常做得很糟糕,或者更确切地说根本没有效率。但您始终可以直接处理底层 numpy 数组:

import pandas as pd
import numpy as np

data=pd.DataFrame(dict(high=[None,100,None,110,None,120,100,None,None,None,None,None,110,None],
                    low=[None,None,50,None,None,None,None,None,30,None,20,None,None,None]))

npdata = data.values
flag = None
flag_index = None
for i in range(len(npdata)):
    if not np.isnan(npdata[i][0]):
        if flag == 'flag_high':
            if npdata[i][0] > npdata[flag_index][0]:
                npdata[flag_index][0] = np.nan
                flag_index = i
            else:
                npdata[i][0] = np.nan
        else:
            flag = 'flag_high'
            flag_index = i
    elif not np.isnan(npdata[i][1]):
        if flag == 'flag_low':
            if npdata[i][1] < npdata[flag_index][1]:
                npdata[flag_index][1] = np.nan
                flag_index = i
            else:
                npdata[i][1] = np.nan
        else:
            flag = 'flag_low'
            flag_index = i

在我的测试中,速度快了近 10 倍。

数据帧越大,增益越高:在 1500 行时,直接使用 numpy 数组速度快 30 倍。

关于python - 如何有效地净化pandas数据框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56215262/

相关文章:

python - python中的Np随机采样

python - 在 sklearn 中尝试交叉验证时出现类型错误

python - 如何安装py.test?

python - 是否可以在Python中的drawcontour中为特定区域着色?

python - Pandas 在相似的列上合并 2 个数据帧(即索引)

python-2.7 - 如何处理在每个单元格中都有一个字典列表的 Pandas 列

python - 如何在 Python 中定义数据框?

python - 将 SRE_Match 对象转换为字符串

python - 如何提取句子中的主语及其各自的从属短语?

python - 基于另一个数据框 pandas 的匹配值的新列