如果 pandas 数据框中包含特定值,则有效过滤窗口观察
Efficiently filter windowed observations in a pandas dataframe if they contain a certain value
我有一个 pandas 数据框,其中 windows/chains 个字符串观察在第一次观察时索引。 window 的大小可变。对于这个例子,我们可以说它们是 4 个观察值的链。我想知道如何最有效地消除某些值,如果它们在 windows 中的任何地方都有特定的观察结果,知道如果第 n 个 window 以我正在寻找的值开头,我知道我可以得到去掉它,以及它之前的三个 windows,因为它们后面的 windows 中也会包含相同的值。 window 可能包含我要过滤的值的多个实例。这是一些示例数据。从一系列简单的事件开始,ser:
import pandas as pd
ser = pd.Series(['a','b','c','d','e','f','g','h','i','j','k'])
>>> ser
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
10 k
然后我把它变成一个数据框,其中每一行都是 window 的 n 个观察值。这里 n == 4.
df = pd.concat([ser.shift(-x) for x in range(4)], axis=1)
>>> df
0 1 2 3
0 a b c d
1 b c d e
2 c d e f
3 d e f g
4 e f g h
5 f g h i
6 g h i j
7 h i j k
8 i j k NaN
9 j k NaN NaN
10 k NaN NaN NaN
现在我想删除任何地方包含值 'f' 的所有行,即:
desired_output
0 1 2 3
0 a b c d
1 b c d e
6 g h i j
7 h i j k
8 i j k NaN
9 j k NaN NaN
10 k NaN NaN NaN
我想避免搜索整个数据框,因为它只包含第一列的重复,而且我的 n 值可能有点长。在此示例中,删除以 'c'、'd'、'e' 和 'f' 开头的列的最佳方法是什么,因为它们都将包含 'f' 某处。后来我将每一行中的所有字符串连接成一个值,但似乎在这个阶段操作数据应该更容易,因为所有内容都在不同的列中。这是 pandas 0.16.0 并且必须在 python 2.76 和 python 3.4 上工作。谢谢!
您可以这样做,无需搜索整个数据框:
import numpy as np
ind = -np.arange(0, df.shape[1])+pd.Index(ser).get_loc('f')
df.iloc[np.setdiff1d(ser.index, ind)]
#Out[48]:
# 0 1 2 3
#0 a b c d
#1 b c d e
#6 g h i j
#7 h i j k
#8 i j k NaN
#9 j k NaN NaN
#10 k NaN NaN NaN
在连接之前只搜索原始序列,用 nans 替换值,然后删除那些在 pandas 中成本较低的操作的 nans 会更有效。
ser = pd.Series(['a','b','c','d','e','f','g','h','i','j','k'])
ser.replace('f', float('nan'), inplace=True)
df = pd.concat([ser.shift(-x) for x in range(4)], axis=1)
df.dropna(inplace=True)
与 Beauvel 上校的解决方案相比,它的优点是能够接受一个可迭代的字符串作为第一个参数并同时过滤多个字符串。另一个区别是它消除了所有可能有问题但在我的情况下是可取的 NA 值。
我有一个 pandas 数据框,其中 windows/chains 个字符串观察在第一次观察时索引。 window 的大小可变。对于这个例子,我们可以说它们是 4 个观察值的链。我想知道如何最有效地消除某些值,如果它们在 windows 中的任何地方都有特定的观察结果,知道如果第 n 个 window 以我正在寻找的值开头,我知道我可以得到去掉它,以及它之前的三个 windows,因为它们后面的 windows 中也会包含相同的值。 window 可能包含我要过滤的值的多个实例。这是一些示例数据。从一系列简单的事件开始,ser:
import pandas as pd
ser = pd.Series(['a','b','c','d','e','f','g','h','i','j','k'])
>>> ser
0 a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
10 k
然后我把它变成一个数据框,其中每一行都是 window 的 n 个观察值。这里 n == 4.
df = pd.concat([ser.shift(-x) for x in range(4)], axis=1)
>>> df
0 1 2 3
0 a b c d
1 b c d e
2 c d e f
3 d e f g
4 e f g h
5 f g h i
6 g h i j
7 h i j k
8 i j k NaN
9 j k NaN NaN
10 k NaN NaN NaN
现在我想删除任何地方包含值 'f' 的所有行,即:
desired_output
0 1 2 3
0 a b c d
1 b c d e
6 g h i j
7 h i j k
8 i j k NaN
9 j k NaN NaN
10 k NaN NaN NaN
我想避免搜索整个数据框,因为它只包含第一列的重复,而且我的 n 值可能有点长。在此示例中,删除以 'c'、'd'、'e' 和 'f' 开头的列的最佳方法是什么,因为它们都将包含 'f' 某处。后来我将每一行中的所有字符串连接成一个值,但似乎在这个阶段操作数据应该更容易,因为所有内容都在不同的列中。这是 pandas 0.16.0 并且必须在 python 2.76 和 python 3.4 上工作。谢谢!
您可以这样做,无需搜索整个数据框:
import numpy as np
ind = -np.arange(0, df.shape[1])+pd.Index(ser).get_loc('f')
df.iloc[np.setdiff1d(ser.index, ind)]
#Out[48]:
# 0 1 2 3
#0 a b c d
#1 b c d e
#6 g h i j
#7 h i j k
#8 i j k NaN
#9 j k NaN NaN
#10 k NaN NaN NaN
在连接之前只搜索原始序列,用 nans 替换值,然后删除那些在 pandas 中成本较低的操作的 nans 会更有效。
ser = pd.Series(['a','b','c','d','e','f','g','h','i','j','k'])
ser.replace('f', float('nan'), inplace=True)
df = pd.concat([ser.shift(-x) for x in range(4)], axis=1)
df.dropna(inplace=True)
与 Beauvel 上校的解决方案相比,它的优点是能够接受一个可迭代的字符串作为第一个参数并同时过滤多个字符串。另一个区别是它消除了所有可能有问题但在我的情况下是可取的 NA 值。