J'extrais un sous-ensemble de données d'une colonne en fonction des conditions d'une autre colonne remplie.
Je peux obtenir les valeurs correctes mais c'est dans pandas.core.frame.DataFrame. Comment convertir cela en liste?
import pandas as pd
tst = pd.read_csv('C:\\SomeCSV.csv')
lookupValue = tst['SomeCol'] == "SomeValue"
ID = tst[lookupValue][['SomeCol']]
#How To convert ID to a list
Utilisez .values
pour obtenir un numpy.array
, puis .tolist()
pour obtenir une liste.
Par exemple:
import pandas as pd
df = pd.DataFrame({'a':[1,3,5,7,4,5,6,4,7,8,9],
'b':[3,5,6,2,4,6,7,8,7,8,9]})
Résultat:
>>> df['a'].values.tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
ou vous pouvez simplement utiliser
>>> df['a'].tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
Pour supprimer les doublons, vous pouvez effectuer l’une des opérations suivantes:
>>> df['a'].drop_duplicates().values.tolist()
[1, 3, 5, 7, 4, 6, 8, 9]
>>> list(set(df['a'])) # as pointed out by EdChum
[1, 3, 4, 5, 6, 7, 8, 9]
J'aimerais clarifier quelques points:
pandas.Series.tolist()
. Je ne suis pas sûr de savoir pourquoi la réponse la plus votée amène à utiliser pandas.Series.values.tolist()
puisque, autant que je sache, cela ajoute une syntaxe/confusion sans aucun avantage supplémentaire.tst[lookupValue][['SomeCol']]
est une base de données (comme indiqué dans la question), pas une série (comme indiqué dans un commentaire à la question). Ceci est dû au fait que tst[lookupValue]
est un cadre de données et que le découpage en tranches avec [['SomeCol']]
demande une liste de colonnes (cette liste ayant une longueur égale à 1), ce qui entraîne le renvoi d'un cadre de données. Si vous supprimez le jeu supplémentaire de crochets, comme dans tst[lookupValue]['SomeCol']
, alors vous ne demandez qu'une colonne, et non une liste de colonnes, et vous obtenez ainsi une série en retour.pandas.Series.tolist()
, vous devez donc absolument ignorer le deuxième groupe de crochets dans ce cas. Pour votre information, si vous vous retrouvez avec une structure de données à une colonne qui n’est pas aussi facile à éviter, vous pouvez utiliser pandas.DataFrame.squeeze()
pour la convertir en série.tst[lookupValue]['SomeCol']
obtient un sous-ensemble d'une colonne particulière via un découpage en chaîne. Il coupe en tranches une fois pour obtenir une image de données avec seulement certaines lignes, puis de nouveau en tranches pour obtenir une certaine colonne. Vous pouvez vous en tirer ici puisque vous ne faites que lire, pas écrire, mais la bonne façon de le faire est tst.loc[lookupValue, 'SomeCol']
(qui renvoie une série).ID = tst.loc[tst['SomeCol'] == 'SomeValue', 'SomeCol'].tolist()
Code de démonstration:
import pandas as pd
df = pd.DataFrame({'colA':[1,2,1],
'colB':[4,5,6]})
filter_value = 1
print "df"
print df
print type(df)
rows_to_keep = df['colA'] == filter_value
print "\ndf['colA'] == filter_value"
print rows_to_keep
print type(rows_to_keep)
result = df[rows_to_keep]['colB']
print "\ndf[rows_to_keep]['colB']"
print result
print type(result)
result = df[rows_to_keep][['colB']]
print "\ndf[rows_to_keep][['colB']]"
print result
print type(result)
result = df[rows_to_keep][['colB']].squeeze()
print "\ndf[rows_to_keep][['colB']].squeeze()"
print result
print type(result)
result = df.loc[rows_to_keep, 'colB']
print "\ndf.loc[rows_to_keep, 'colB']"
print result
print type(result)
result = df.loc[df['colA'] == filter_value, 'colB']
print "\ndf.loc[df['colA'] == filter_value, 'colB']"
print result
print type(result)
ID = df.loc[rows_to_keep, 'colB'].tolist()
print "\ndf.loc[rows_to_keep, 'colB'].tolist()"
print ID
print type(ID)
ID = df.loc[df['colA'] == filter_value, 'colB'].tolist()
print "\ndf.loc[df['colA'] == filter_value, 'colB'].tolist()"
print ID
print type(ID)
Résultat:
df
colA colB
0 1 4
1 2 5
2 1 6
<class 'pandas.core.frame.DataFrame'>
df['colA'] == filter_value
0 True
1 False
2 True
Name: colA, dtype: bool
<class 'pandas.core.series.Series'>
df[rows_to_keep]['colB']
0 4
2 6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df[rows_to_keep][['colB']]
colB
0 4
2 6
<class 'pandas.core.frame.DataFrame'>
df[rows_to_keep][['colB']].squeeze()
0 4
2 6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[rows_to_keep, 'colB']
0 4
2 6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[df['colA'] == filter_value, 'colB']
0 4
2 6
Name: colB, dtype: int64
<class 'pandas.core.series.Series'>
df.loc[rows_to_keep, 'colB'].tolist()
[4, 6]
<type 'list'>
df.loc[df['colA'] == filter_value, 'colB'].tolist()
[4, 6]
<type 'list'>
Vous pouvez utiliser pandas.Series.tolist
par exemple.:
import pandas as pd
df = pd.DataFrame({'a':[1,2,3], 'b':[4,5,6]})
Courir:
>>> df['a'].tolist()
Tu auras
>>> [1, 2, 3]
La solution ci-dessus est bonne si toutes les données sont du même type. Les tableaux Numpy sont des conteneurs homogènes. Quand vous faites df.values
, le résultat est un numpy array
. Ainsi, si les données contiennent int
et float
, alors la sortie aura soit int
ou float
et les colonnes perdront leur type d'origine. Considérez df
a b
0 1 4
1 2 5
2 3 6
a float64
b int64
Donc, si vous voulez conserver le type d'origine, vous pouvez faire quelque chose comme
row_list = df.to_csv(None, header=False, index=False).split('\n')
cela retournera chaque ligne sous forme de chaîne.
['1.0,4', '2.0,5', '3.0,6', '']
Puis divisez chaque ligne pour obtenir la liste. Chaque élément après division est un unicode. Nous devons convertir le type de données requis.
def f(row_str):
row_list = row_str.split(',')
return [float(row_list[0]), int(row_list[1])]
df_list_of_list = map(f, row_list[:-1])
[[1.0, 4], [2.0, 5], [3.0, 6]]