3 votes

Les pandas ajoutent une variable comme colonne et correspondent au tableau original (mais ils ont une longueur différente).

Ce que je demande est un peu compliqué, comme le titre. J'ai créé cet exemple pour vous montrer ma question. Voici le tableau de l'exemple :

df = pd.DataFrame({'Number': [1,2,3,4,5,6,7,8,9], 'Col1':['a','b','c','d','e','f','g','h','i']})

L'étape suivante consiste à extraire df['Number'] et à lancer l'itération pour une raison quelconque. number= [i*i for i in df['Number']] le résultat est [1, 4, 9, 16, 25, 36, 49, 64, 81]

J'ai maintenant une variable 'nombre' qui est une liste.

Maintenant, l'étape clé est que je dois regrouper cette liste. Disons que le numéro est inférieur à 40.

number1 = [i for i in number if i < 40]
number2 = [i for i in number if i > 40]

OK, l'étape clé que je veux est d'ajouter le numéro 1 et le numéro 2 à df, mais le résultat final attendu est comme ceci :

C'est-à-dire que l'on ajoute une nouvelle colonne 'Type' et ces deux nouvelles variables doivent correspondre à l'index et le contenu est 'nombre1' et 'nombre2', mais pas '1,4,9...81'.

3voto

jezrael Points 290608

Je pense que vous avez besoin numpy.where con boolean mask :

print (df.Number.pow(2) < 40)
0     True
1     True
2     True
3     True
4     True
5     True
6    False
7    False
8    False
Name: Number, dtype: bool

df['Type'] = np.where(df.Number.pow(2) < 40, 'number1', 'number2')
#same as
#df['Type'] = np.where(df.Number ** 2 < 40, 'number1', 'number2')
#another solution
#df['Type'] = np.where(df.Number.pow(2).lt(40), 'number1', 'number2')
print (df)
  Col1  Number     Type
0    a       1  number1
1    b       2  number1
2    c       3  number1
3    d       4  number1
4    e       5  number1
5    f       6  number1
6    g       7  number2
7    h       8  number2
8    i       9  number2

Horaires - numpy.where est le plus rapide :

df = pd.DataFrame({'Number': [1,2,3,4,5,6,7,8,9], 'Col1':['a','b','c','d','e','f','g','h','i']})
#[9000 rows x 5 columns]
df = pd.concat([df]*1000).reset_index(drop=True)

df['Type'] = np.where(df.Number.pow(2).lt(40), 'number1', 'number2')

df['Type1'] = 'number' + (1 + ((df.Number**2)>40).astype(int)).astype(str)

# Rule to produce new values
def f(row):
    if row['Number']**2 > 40:
        val = 'Number2'
    else:
        val = 'Number1'
    return val

df['Type2'] = df.apply(f, axis=1)

#print (df)

In [218]: %timeit df['Type'] = np.where(df.Number.pow(2).lt(40), 'number1', 'number2')
1000 loops, best of 3: 1.63 ms per loop

In [219]: %timeit df['Type1'] = 'number' + (1 + ((df.Number**2)>40).astype(int)).astype(str)
100 loops, best of 3: 13.5 ms per loop

In [220]: %timeit df['Type2'] = df.apply(f, axis=1)
10 loops, best of 3: 127 ms per loop

EDITAR:

Je crée des colonnes d'aide pour mieux comprendre la comparaison :

df['pow'] = df.Number.pow(2)
df['comaping val'] = 40
df['val'] = df.Number.pow(2).lt(40)
print (df)
  Col1  Number  pow  comaping val    val
0    a       1    1            40   True
1    b       2    4            40   True
2    c       3    9            40   True
3    d       4   16            40   True
4    e       5   25            40   True
5    f       6   36            40   True
6    g       7   49            40  False
7    h       8   64            40  False
8    i       9   81            40  False

2voto

MaxU Points 5284

Voici mon approche créative :

Données :

In [23]: df
Out[23]:
  Col1  Number
0    a       1
1    b       2
2    c       3
3    d       4
4    e       5
5    f       6
6    g       7
7    h       8
8    i       9

Solution :

In [24]: df['Type'] = 'number' + (1 + ((df.Number**2)>40).astype(int)).astype(str)

Résultat :

In [25]: df
Out[25]:
  Col1  Number     Type
0    a       1  number1
1    b       2  number1
2    c       3  number1
3    d       4  number1
4    e       5  number1
5    f       6  number1
6    g       7  number2
7    h       8  number2
8    i       9  number2

Explication :

In [29]: ((df.Number**2)>40).astype(int)
Out[29]:
0    0
1    0
2    0
3    0
4    0
5    0
6    1
7    1
8    1
Name: Number, dtype: int32

In [30]: 1 + ((df.Number**2)>40).astype(int)
Out[30]:
0    1
1    1
2    1
3    1
4    1
5    1
6    2
7    2
8    2
Name: Number, dtype: int32

1voto

Serenity Points 16825

Créez une fonction personnalisée et utilisez-la ensuite dans pandas.apply

import pandas as pd

# Rule to produce new values
def f(row):
    if row['Number']**2 > 40:
        val = 'Number2'
    else:
        val = 'Number1'
    return val

df = pd.DataFrame({'Number': [1,2,3,4,5,6,7,8,9], 'Col1':['a','b','c','d','e','f','g','h','i']})

# Apply the function to construct new column
df['Type'] = df.apply(f, axis=1)
print (df)

Sortie :

 Col1  Number     Type
0    a       1  Number1
1    b       2  Number1
2    c       3  Number1
3    d       4  Number1
4    e       5  Number1
5    f       6  Number1
6    g       7  Number2
7    h       8  Number2
8    i       9  Number2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X