python - seleccionar - Pandas DataFrame a la lista
seleccionar columnas pandas python (4)
Estoy extrayendo un subconjunto de datos de una columna en función de las condiciones en otra columna que se cumplen.
Puedo recuperar los valores correctos pero está en pandas.core.frame.DataFrame. ¿Cómo convierto eso a la lista?
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
La solución anterior es buena si todos los datos son del mismo tipo. Las matrices Numpy son contenedores homogéneos. Cuando haces df.values
la salida es una numpy array
. Entonces, si los datos tienen int
y float
, la salida tendrá int
o float
y las columnas perderán su dtype original. Considera df
a b
0 1 4
1 2 5
2 3 6
a float64
b int64
Entonces, si quieres conservar el tipo de letra original, puedes hacer algo como
row_list = df.to_csv(None, header=False, index=False).split(''/n'')
esto devolverá cada fila como una cadena.
[''1.0,4'', ''2.0,5'', ''3.0,6'', '''']
Luego divide cada fila para obtener la lista de la lista. Cada elemento después de la división es unicode. Necesitamos convertir el tipo de datos requerido.
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]]
Me gustaría aclarar algunas cosas:
- Como han señalado otras respuestas, lo más simple es utilizar
pandas.Series.tolist()
. No estoy seguro de por qué la respuesta más votado comienza con el uso depandas.Series.values.tolist()
ya que, por lo que puedo decir, agrega sintaxis / confusión sin ningún beneficio adicional. -
tst[lookupValue][[''SomeCol'']]
es un marco de datos (como se indica en la pregunta), no una serie (como se indica en un comentario de la pregunta). Esto se debe a quetst[lookupValue]
es un marco de datos, y al cortarlo con[[''SomeCol'']]
pide una lista de columnas (esa lista que tiene una longitud de 1), lo que da como resultado que se devuelva un marco de datos. Si quita el conjunto adicional de corchetes, como entst[lookupValue][''SomeCol'']
, entonces está pidiendo solo esa columna en lugar de una lista de columnas, y así obtiene una serie. - Necesita una serie para usar
pandas.Series.tolist()
, por lo que definitivamente debe omitir el segundo conjunto de corchetes en este caso. FYI, si alguna vez termina con un marco de datos de una columna que no se puede evitar fácilmente de esta manera, puede usarpandas.DataFrame.squeeze()
para convertirlo en una serie. -
tst[lookupValue][''SomeCol'']
está obteniendo un subconjunto de una columna particular a través de un corte encadenado. Corta una vez para obtener un marco de datos con solo algunas filas, y luego vuelve a cortar para obtener una determinada columna. Puede salirse con la suya aquí ya que solo está leyendo, no escribiendo, pero la forma correcta de hacerlo estst.loc[lookupValue, ''SomeCol'']
(que devuelve una serie). - Utilizando la sintaxis del n. ° 4, podría hacer razonablemente todo en una línea:
ID = tst.loc[tst[''SomeCol''] == ''SomeValue'', ''SomeCol''].tolist()
Código de demostración:
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)
Resultado:
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''>
Puedes usar pandas.Series.tolist
p.ej:
import pandas as pd
df = pd.DataFrame({''a'':[1,2,3], ''b'':[4,5,6]})
Correr:
>>> df[''a''].tolist()
Conseguirás
>>> [1, 2, 3]
Usa .values
para obtener un numpy.array
y luego .tolist()
para obtener una lista.
Por ejemplo:
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]})
Resultado:
>>> df[''a''].values.tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
o simplemente puedes usar
>>> df[''a''].tolist()
[1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9]
Para eliminar duplicados, puede hacer una de las siguientes cosas:
>>> 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]