Existe-t-il un moyen de sélectionner plusieurs colonnes qui ne sont pas adjacentes et de combiner plusieurs méthodes?
test dataframe:
frames = [test.loc[:, 'ID'], test.loc[:, test.columns.str.startswith('rfm')], test.loc[:, 'a':'c'], test.iloc[:, -1]] test_sub = pd.concat(frames)
Disons que je veux les colonnes: ID, toutes les colonnes commençant par rfm, a: c et e . Dans cet ordre.
Je pensais que quelque chose de ce genre le ferait, mais je n'ai pas été en mesure de le faire fonctionner
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'])
J'ai lu qu'il réinitialise le index et que je ne pourrai pas contrôler l'ordre des colonnes.
De préférence, il y aurait quelque chose comme np.r_
pour .loc
pour combiner les tranches telles que trouvées dans cet article
Mais je n'aime pas utiliser la position d'index quand je fais référence aux colonnes
Toute aide est très appréciée
3 Réponses :
voici une manière d'utiliser np.r_
et get_loc () et get_indexer ()
:
ID rfm_snittbeløp_gaver rfm_maksbeløp_gaver rfm_antall_kampanjer \ 0 0.822275 0.155649 0.189058 0.050138 1 0.188038 0.286731 0.509774 0.171374 2 0.626211 0.477937 0.585987 0.358124 a b c e 0 0.652142 0.492184 0.464453 0.361395 1 0.242480 0.963673 0.898177 0.813195 2 0.863088 0.781858 0.924203 0.690219
test.iloc[:,np.r_[ID,rfm,a:c+1,e]]
ID= test.columns.get_loc('ID') rfm=test.columns.get_indexer(test.columns[test.columns.str.startswith('rfm')]) a=test.columns.get_loc('a') c=test.columns.get_loc('c') e=test.columns.get_loc('e')
C'était assez chouette, mais que se passerait-il si j'aurais voulu des colonnes de a: p, alors j'aurais besoin de créer beaucoup de get_locs ...
@Jon non, vous auriez encore besoin de seulement 2 get loc. a: c + 1
vous donne l'index de la plage de a à c, pour a: p
remplacez c
par p code> dans la solution
ah, je vois maintenant. Donc, avec juste une fonction personnalisée en plus de cela pour faire les get_locs, c'est génial. Ensuite, je peux simplement passer dans les colonnes que je veux et trancher et couper en dés à ma guise!
yep :) aussi cela résoudrait que vous n'aimiez pas utiliser la position d'index lorsque vous vous référez aux noms de colonnes. c'est une bonne fonctionnalité à avoir à ces fins.
Vous êtes assez proche, avec axis=1
:
frames = [test.loc[:, 'ID'], test.loc[:, test.columns.str.startswith('rfm')], test.loc[:, 'a':'c'], test.iloc[:, -1]] test_sub = pd.concat(frames, axis=1)
Une approche plus générale sera de créer une classe comme la suivante:
0 0.129801 1 0.786684 2 0.839015 Name: ID, dtype: float64
Vous pourriez alors faire:
print(test.loc[:, s_(test.columns)['ID']])
Sortie
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]
Notez que cela fonctionne également pour l'indexation simple:
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]])
Sortie
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]
par
a: c
voulez-vous direa, b, c
inclus?