Python 如何按名称选择多个不相邻的列,并结合多种切片方法?

Python 如何按名称选择多个不相邻的列,并结合多种切片方法?,python,pandas,slice,Python,Pandas,Slice,有没有一种方法可以选择多个不相邻的列并结合多种方法 测试数据帧: test = pd.DataFrame(np.random.rand(3, 9), columns=['ID', 'rfm_snittbeløp_gaver', 'rfm_maksbeløp_gaver', 'rfm_antall_kampanjer', 'a','b','c','d','e']) 假设我想要列:ID,所有以rfm、

有没有一种方法可以选择多个不相邻的列并结合多种方法

测试数据帧:

test = pd.DataFrame(np.random.rand(3, 9),
                    columns=['ID', 'rfm_snittbeløp_gaver', 'rfm_maksbeløp_gaver', 'rfm_antall_kampanjer',
                             'a','b','c','d','e'])
假设我想要列:ID,所有以rfm、a:c和e开头的列。按这个顺序

我原以为这样做就行了,但我没能成功

frames = [test.loc[:, 'ID'],
          test.loc[:, test.columns.str.startswith('rfm')],
          test.loc[:, 'a':'c'],
          test.iloc[:, -1]]

test_sub = pd.concat(frames)
我读到它重置了索引,我将无法控制列的顺序

最好有类似于np.r_2;for.loc的东西来组合本文中的切片

但我不喜欢在引用列时使用索引位置

非常感谢您的帮助

以下是使用和的方法:

以下是使用and和的方法:


很接近,轴=1:


很接近,轴=1:


更通用的方法是创建如下类:

class s_:
    """Create slices from given columns resembling numpy s_"""

    def __init__(self, cols):
        self.indices = pd.Series(cols, index=cols)

    def __getitem__(self, item):
        if isinstance(item, tuple):
            result = []
            for indexing in item:
                try:
                    if isinstance(indexing, str): # treat strings as labels
                        result.append(self.indices[indexing])
                    else:
                        result.extend(self.indices[indexing])
                except TypeError:
                    result.append(self.indices[indexing])
            return result
        else:
            return self.indices[item]
你可以这样做:

columns = ['ID', 'rfm_snittbeløp_gaver', 'rfm_maksbeløp_gaver', 'rfm_antall_kampanjer', 'a', 'b', 'c', 'd', 'e']
test = pd.DataFrame(np.random.rand(3, 9), columns=columns)

print(test.loc[:, s_(test.columns)['ID', test.columns.str.startswith('rfm'), 'a':'c', -1]])
输出

请注意,这也适用于单个索引:

print(test.loc[:, s_(test.columns)['ID']])
输出


更通用的方法是创建如下类:

class s_:
    """Create slices from given columns resembling numpy s_"""

    def __init__(self, cols):
        self.indices = pd.Series(cols, index=cols)

    def __getitem__(self, item):
        if isinstance(item, tuple):
            result = []
            for indexing in item:
                try:
                    if isinstance(indexing, str): # treat strings as labels
                        result.append(self.indices[indexing])
                    else:
                        result.extend(self.indices[indexing])
                except TypeError:
                    result.append(self.indices[indexing])
            return result
        else:
            return self.indices[item]
你可以这样做:

columns = ['ID', 'rfm_snittbeløp_gaver', 'rfm_maksbeløp_gaver', 'rfm_antall_kampanjer', 'a', 'b', 'c', 'd', 'e']
test = pd.DataFrame(np.random.rand(3, 9), columns=columns)

print(test.loc[:, s_(test.columns)['ID', test.columns.str.startswith('rfm'), 'a':'c', -1]])
输出

请注意,这也适用于单个索引:

print(test.loc[:, s_(test.columns)['ID']])
输出


你说的a:c是指a,b,c包括在内吗?a:c是指a,b,c包括在内吗?这很好,但是如果我想要a:p中的列,那么我需要创建很多get_loc。@Jon不,你仍然需要2个get loc。a:c+1给出了从a到c范围的指数,对于a:p,在溶液中用p替换c,我明白了。因此,只需在此基础上添加一个自定义函数,即可执行get_locs操作,这真是太棒了。然后我就可以通过我想要的栏目,切块切丁,我的心的内容!是的:这也可以解决在引用列名时不喜欢使用索引位置的问题。这是一个很好的特性,非常简洁,但是如果我想要a:p中的列,那么我需要创建很多get_loc.@Jon不,你仍然需要2个get loc。a:c+1给出了从a到c范围的指数,对于a:p,在溶液中用p替换c,我明白了。因此,只需在此基础上添加一个自定义函数,即可执行get_locs操作,这真是太棒了。然后我就可以通过我想要的栏目,切块切丁,我的心的内容!是的:这也可以解决在引用列名时不喜欢使用索引位置的问题。这是一个很好的特点,有这样的目的。
         ID  rfm_snittbeløp_gaver  ...         c         e
0  0.026803              0.603409  ...  0.819486  0.396006
1  0.791049              0.450502  ...  0.097529  0.708746
2  0.623558              0.513678  ...  0.140740  0.958713

[3 rows x 8 columns]
print(test.loc[:, s_(test.columns)['ID']])
0    0.129801
1    0.786684
2    0.839015
Name: ID, dtype: float64