c'est à dire.:
import pandas
d = {'col1': 2, 'col2': 2.5}
df = pandas.DataFrame(data=d, index=[0])
print(df['col2'])
print(df.col2)
La sortie est la même.
Cette réponse s'applique-t-elle à ce cas?
Quelle est la différence entre les notations entre crochets et points en Python?
La "notation par points", c'est-à-dire df.col2
est le accès aux attributs qui est présenté par commodité.
Vous pouvez accéder à un index sur une série, une colonne sur un DataFrame et un élément sur un panneau directement en tant qu'attribut:
df['col2']
fait de même: il renvoie un pd.Series
de la colonne.
Quelques mises en garde concernant l'accès aux attributs:
df.new_col = x
ne fonctionnera pas, pire: il silencieusement créera en fait un nouvel attribut plutôt qu'une colonne - pensez au patch de singe ici)Ils sont les mêmes tant que vous accédez à une seule colonne avec un nom simple, mais vous pouvez faire plus avec la notation entre crochets. Vous ne pouvez utiliser que df.col
si le nom de la colonne est un identifiant valide Python (par exemple, ne contient pas d'espaces et d'autres éléments de ce type). En outre, vous pouvez rencontrer des surprises si le nom de votre colonne se heurte à un pandas nom de la méthode (comme sum
). Avec des crochets, vous pouvez sélectionner plusieurs colonnes (par exemple, df[['col1', 'col2']]
) ou ajoutez une nouvelle colonne (df['newcol'] = ...
), ce qui ne peut pas être fait avec un accès par points.
L'autre question à laquelle vous avez lié s'applique, mais c'est une question beaucoup plus générale. Python définissent comment les .
et []
les opérateurs s'appliquent à eux. Pandas DataFrames ont choisi de les rendre identiques pour ce cas limité d'accès à des colonnes uniques, avec les mises en garde décrites ci-dessus.
Réponse courte aux différences:
[]
l'indexation (accès entre crochets) a toutes les fonctionnalités pour fonctionner sur les données de la colonne DataFrame.Plus d'explications, Seires et DataFrame sont des classes de base et des structures de données dans les pandas, et bien sûr, ce sont des classes Python aussi, donc il y a une distinction mineure lors de l'accès aux attributs entre pandas DataFrame et normal Python objets. Mais c'est bien documenté et peut être facilement compris. Juste quelques points à noter:
En Python, les utilisateurs peuvent ajouter dynamiquement leurs propres attributs de données à un objet d'instance en utilisant l'accès aux attributs.
>>> class Dog(object):
... pass
>>> dog = Dog()
>>> vars(dog)
{}
>>> superdog = Dog()
>>> vars(superdog)
{}
>>> dog.legs = 'I can run.'
>>> superdog.wings = 'I can fly.'
>>> vars(dog)
{'legs': 'I can run.'}
>>> vars(superdog)
{'wings': 'I can fly.'}
Dans les pandas, index et colonne sont étroitement liés à la structure des données, vous pouvez accéder un index sur une série, une colonne sur un DataFrame comme attribut .
>>> import pandas as pd
>>> import numpy as np
>>> data = np.random.randint(low=0, high=10, size=(2,2))
>>> df = pd.DataFrame(data, columns=['a', 'b'])
>>> df
a b
0 7 6
1 5 8
>>> vars(df)
{'_is_copy': None,
'_data': BlockManager
Items: Index(['a', 'b'], dtype='object')
Axis 1: RangeIndex(start=0, stop=2, step=1)
IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64,
'_item_cache': {}}
Mais, pandas est principalement un moyen pratique pour lire et modifier un élément existant d'une série ou d'une colonne de un DataFrame.
>>> df.a
0 7
1 5
Name: a, dtype: int64
>>> df.b = [1, 1]
>>> df
a b
0 7 1
1 5 1
Et, la commodité est un compromis pour une fonctionnalité complète. Par exemple. vous pouvez créer un objet DataFrame avec des noms de colonne ['space bar', '1', 'loc', 'min', 'index']
, mais vous ne pouvez pas y accéder en tant qu'attribut, car ce n'est pas un identifiant valide Python 1
, space bar
ou entre en conflit avec un nom de méthode existant.
>>> data = np.random.randint(0, 10, size=(2, 5))
>>> df_special_col_names = pd.DataFrame(data, columns=['space bar', '1', 'loc', 'min', 'index'])
>>> df_special_col_names
space bar 1 loc min index
0 4 4 4 8 9
1 3 0 1 2 3
Dans ces cas, le .loc
, .iloc
et []
l'indexation est de la manière définie pour accéder/utiliser pleinement l'index et les colonnes des objets Series et DataFrame.
>>> df_special_col_names['space bar']
0 4
1 3
Name: space bar, dtype: int64
>>> df_special_col_names.loc[:, 'min']
0 8
1 2
Name: min, dtype: int64
>>> df_special_col_names.iloc[:, 1]
0 4
1 0
Name: 1, dtype: int64
Une autre différence importante est lors de la création d'une nouvelle colonne pour DataFrame. Comme vous pouvez le voir, df.c = df.a + df.b
juste créé un nouvel attribut à côté de la structure de données principale , donc à partir de la version 0.21.0
et plus tard, ce comportement fera monter un UserWarning
(plus de silence).
>>> df
a b
0 7 1
1 5 1
>>> df.c = df.a + df.b
__main__:1: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
>>> df['d'] = df.a + df.b
>>> df
a b d
0 7 1 8
1 5 1 6
>>> df.c
0 8
1 6
dtype: int64
>>> vars(df)
{'_is_copy': None,
'_data':
BlockManager
Items: Index(['a', 'b', 'd'], dtype='object')
Axis 1: RangeIndex(start=0, stop=2, step=1)
IntBlock: slice(0, 2, 1), 2 x 2, dtype: int64
IntBlock: slice(2, 3, 1), 1 x 2, dtype: int64,
'_item_cache': {},
'c': 0 8
1 6
dtype: int64}
Enfin, pour créer une nouvelle colonne pour DataFrame, n'utilisez jamais l'accès aux attributs , la bonne façon est de utiliser soit []
ou .loc
indexation :
>>> df
a b
0 7 6
1 5 8
>>> df['c'] = df.a + df.b
>>> # OR
>>> df.loc[:, 'c'] = df.a + df.b
>>> df # c is an new added column
a b c
0 7 6 13
1 5 8 13