如何逐个创建DataFrame切片对象?

blu*_*e13 11 python pandas

我有一个DataFrame,我想从中选择某些行和列.我知道如何使用loc.但是,我希望能够单独指定每个条件,而不是一次性指定.

import numpy as np
import pandas as pd
idx = pd.IndexSlice

index = [np.array(['foo', 'foo', 'qux', 'qux']),
         np.array(['a', 'b', 'a', 'b'])]
columns = ["A",  "B"]
df = pd.DataFrame(np.random.randn(4, 2), index=index, columns=columns)
print df
print df.loc[idx['foo', :], idx['A':'B']]

              A         B
foo a  0.676649 -1.638399
    b -0.417915  0.587260
qux a  0.294555 -0.573041
    b  1.592056  0.237868


              A         B
foo a -0.470195 -0.455713
    b  1.750171 -0.409216
Run Code Online (Sandbox Code Playgroud)

需求

我希望能够使用类似下面的代码来实现相同的结果,其中我逐个指定每个条件.同样重要的是我能够使用a slice_list来允许动态行为[即语法应该有效,无论是否有两个,三个或十个不同的标准slice_list].

slice_1 = 'foo'
slice_2 = ':'
slice_list = [slice_1, slice_2]

column_slice = "'A':'B'"
print df.loc[idx[slice_list], idx[column_slice]]
Run Code Online (Sandbox Code Playgroud)

Ted*_*rou 9

您可以使用slice内置功能实现此目的.您不能使用字符串构建切片,因为':'是文字字符而不是合成字符.

slice_1 = 'foo'
slice_2 = slice(None)
column_slice = slice('A', 'B')
df.loc[idx[slice_1, slice_2], idx[column_slice]]
Run Code Online (Sandbox Code Playgroud)


Mic*_*off 2

以 Ted Petrou 的答案为基础:

slices = [('foo', slice(None)), slice('A', 'B')]
print df.loc[tuple(idx[s] for s in slices)]

              A         B
foo a -0.465421 -0.591763
    b -0.854938  1.221204

slices = [('foo', slice(None)), 'A']
print df.loc[tuple(idx[s] for s in slices)]

foo  a   -0.465421
     b   -0.854938
Name: A, dtype: float64

slices = [('foo', slice(None))]
print df.loc[tuple(idx[s] for s in slices)]

              A         B
foo a -0.465421 -0.591763
    b -0.854938  1.221204
Run Code Online (Sandbox Code Playgroud)

当使用“动态”参数调用__getitem__( )时,必须使用元组。loc[...]

您还可以避免slice手动构建对象:

def to_selector(s):
    if isinstance(s, tuple) or isinstance(s, list):
        return tuple(map(to_selector, s))
    ps = [None if len(p) == 0 else p for p in s.split(':')]
    assert len(ps) > 0 and len(ps) <= 2
    if len(ps) == 1:
        assert ps[0] is not None
        return ps[0]
    return slice(*ps)

query = [('foo', ':'), 'A:B']
df.loc[tuple(idx[to_selector(s)] for s in query)]
Run Code Online (Sandbox Code Playgroud)