ottenere l'elenco dalla colonna del frame di dati di Panda


289

Ho un documento eccellente che assomiglia a questo ...

cluster load_date   budget  actual  fixed_price
A   1/1/2014    1000    4000    Y
A   2/1/2014    12000   10000   Y
A   3/1/2014    36000   2000    Y
B   4/1/2014    15000   10000   N
B   4/1/2014    12000   11500   N
B   4/1/2014    90000   11000   N
C   7/1/2014    22000   18000   N
C   8/1/2014    30000   28960   N
C   9/1/2014    53000   51200   N

Voglio essere in grado di restituire il contenuto della colonna 1 - cluster come un elenco, in modo da poter eseguire un ciclo for su di esso e creare un foglio di lavoro Excel per ogni cluster.

È anche possibile riportare il contenuto di un'intera riga in un elenco? per esempio

list = [], list[column1] or list[df.ix(row1)]

10
Le colonne di panda dei frame di dati sono una serie di panda quando le estrai, che puoi chiamare .tolist()per trasformarle in un elenco di pitoni
Ben

4
Dalla v0.24 in poi, .valuesNON SARÀ PIÙ il metodo preferito per accedere alle matrici numpy sottostanti. Vedere questa risposta .
1919

Nota importante: la conversione di una serie Pandas in un elenco o in un array NumPy è spesso superflua, e quasi certamente è nel caso di OP.
AMC

1
Inoltre, non è necessario leggere le risposte troppo lunghe per una domanda così banale. df.to_numpy().tolist()dovrebbe andare bene per la maggior parte dei casi d'uso.
AMC

1
Semplicemente digita utilizzandolist(x)
Pe Dro

Risposte:


497

Le colonne Pandas DataFrame sono Pandas Series quando vengono estratte, che è quindi possibile richiamare x.tolist()per trasformarle in un elenco Python. In alternativa, puoi lanciarlo con list(x).

import pandas as pd

data_dict = {'one': pd.Series([1, 2, 3], index=['a', 'b', 'c']),
             'two': pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(data_dict)

print(f"DataFrame:\n{df}\n")
print(f"column types:\n{df.dtypes}")

col_one_list = df['one'].tolist()

col_one_arr = df['one'].to_numpy()

print(f"\ncol_one_list:\n{col_one_list}\ntype:{type(col_one_list)}")
print(f"\ncol_one_arr:\n{col_one_arr}\ntype:{type(col_one_arr)}")

Produzione:

DataFrame:
   one  two
a  1.0    1
b  2.0    2
c  3.0    3
d  NaN    4

column types:
one    float64
two      int64
dtype: object

col_one_list:
[1.0, 2.0, 3.0, nan]
type:<class 'list'>

col_one_arr:
[ 1.  2.  3. nan]
type:<class 'numpy.ndarray'>

24
Non riesco a orientarmi nello stile dei documenti, perché è quasi sempre una sintassi semplice, dove ho bisogno di sintassi ed esempio. Ad esempio, la sintassi sarebbe quella di creare un set: utilizzare la parola chiave set e un elenco: Esempio di accompagnamento: alist = df.cluster.tolist (). Finché i panda non saranno scritti in questo modo, farò fatica. ci sta arrivando, ora ci sono alcuni esempi, ma non per tutti i metodi.
yoshiserry,

Grazie @ Ben, ottima risposta! Puoi parlarmi del metodo Dataframe, non l'ho mai visto prima ... sembra che tu stia convertendo un dictionary in un df? df = DataFrame (d)?
yoshiserry,

Uno dei modi predefiniti per creare un dataframe è passargli un elenco di dizionari con chiavi corrispondenti.
Ben

2
La maggior parte delle funzioni comuni di @yoshiserry ora hanno un esempio di utilizzo nella loro documentazione, sotto la sintassi e l'elenco degli argomenti. Puoi anche vedere 15 minuti di panda per altri esempi di livello per principianti.
cs95,

2
@Ben Non ti avevo visto ancora attivo su SO, volevo menzionare che ho inviato una modifica di dimensioni adeguate a questa risposta, quindi fammi sapere cosa ne pensi :)
AMC

54

Ciò restituisce una matrice numpy:

arr = df["cluster"].to_numpy()

Ciò restituisce una matrice numpy di valori univoci :

unique_arr = df["cluster"].unique()

Puoi anche usare numpy per ottenere valori univoci, anche se ci sono differenze tra i due metodi:

arr = df["cluster"].to_numpy()
unique_arr = np.unique(arr)

4

Esempio di conversione:

Array Numpy -> Panda Data Frame -> Elenco da una colonna Panda

Matrice numpy

data = np.array([[10,20,30], [20,30,60], [30,60,90]])

Converti l'array numpy nel frame di dati Panda

dataPd = pd.DataFrame(data = data)

print(dataPd)
0   1   2
0  10  20  30
1  20  30  60
2  30  60  90

Converti un frame Panda in elenco

pdToList = list(dataPd['2'])


1
Perché mostrare due volte il codice di creazione dell'array, come se fosse una parte importante della soluzione? Perché persino creare quell'array, in effetti? Non è df = pd.DataFrame(data=[[10, 20, 30], [20, 30, 60], [30, 60, 90]])più semplice? Inoltre, nota il nome della variabile e gli spazi bianchi che seguono le convenzioni di stile Python. Scorri l'elenco come prova Cosa dimostra esattamente questo? Che è un elenco?
AMC

2

Dato che questa domanda ha suscitato molta attenzione e ci sono diversi modi per adempiere al tuo compito, fammi presentare diverse opzioni.

A proposito, quelli sono tutti a una linea;)

Iniziare con:

df
  cluster load_date budget actual fixed_price
0       A  1/1/2014   1000   4000           Y
1       A  2/1/2014  12000  10000           Y
2       A  3/1/2014  36000   2000           Y
3       B  4/1/2014  15000  10000           N
4       B  4/1/2014  12000  11500           N
5       B  4/1/2014  90000  11000           N
6       C  7/1/2014  22000  18000           N
7       C  8/1/2014  30000  28960           N
8       C  9/1/2014  53000  51200           N

Panoramica delle potenziali operazioni:

ser_aggCol (collapse each column to a list)
cluster          [A, A, A, B, B, B, C, C, C]
load_date      [1/1/2014, 2/1/2014, 3/1/2...
budget         [1000, 12000, 36000, 15000...
actual         [4000, 10000, 2000, 10000,...
fixed_price      [Y, Y, Y, N, N, N, N, N, N]
dtype: object


ser_aggRows (collapse each row to a list)
0     [A, 1/1/2014, 1000, 4000, Y]
1    [A, 2/1/2014, 12000, 10000...
2    [A, 3/1/2014, 36000, 2000, Y]
3    [B, 4/1/2014, 15000, 10000...
4    [B, 4/1/2014, 12000, 11500...
5    [B, 4/1/2014, 90000, 11000...
6    [C, 7/1/2014, 22000, 18000...
7    [C, 8/1/2014, 30000, 28960...
8    [C, 9/1/2014, 53000, 51200...
dtype: object


df_gr (here you get lists for each cluster)
                             load_date                 budget                 actual fixed_price
cluster                                                                                         
A        [1/1/2014, 2/1/2014, 3/1/2...   [1000, 12000, 36000]    [4000, 10000, 2000]   [Y, Y, Y]
B        [4/1/2014, 4/1/2014, 4/1/2...  [15000, 12000, 90000]  [10000, 11500, 11000]   [N, N, N]
C        [7/1/2014, 8/1/2014, 9/1/2...  [22000, 30000, 53000]  [18000, 28960, 51200]   [N, N, N]


a list of separate dataframes for each cluster

df for cluster A
  cluster load_date budget actual fixed_price
0       A  1/1/2014   1000   4000           Y
1       A  2/1/2014  12000  10000           Y
2       A  3/1/2014  36000   2000           Y

df for cluster B
  cluster load_date budget actual fixed_price
3       B  4/1/2014  15000  10000           N
4       B  4/1/2014  12000  11500           N
5       B  4/1/2014  90000  11000           N

df for cluster C
  cluster load_date budget actual fixed_price
6       C  7/1/2014  22000  18000           N
7       C  8/1/2014  30000  28960           N
8       C  9/1/2014  53000  51200           N

just the values of column load_date
0    1/1/2014
1    2/1/2014
2    3/1/2014
3    4/1/2014
4    4/1/2014
5    4/1/2014
6    7/1/2014
7    8/1/2014
8    9/1/2014
Name: load_date, dtype: object


just the values of column number 2
0     1000
1    12000
2    36000
3    15000
4    12000
5    90000
6    22000
7    30000
8    53000
Name: budget, dtype: object


just the values of row number 7
cluster               C
load_date      8/1/2014
budget            30000
actual            28960
fixed_price           N
Name: 7, dtype: object


============================== JUST FOR COMPLETENESS ==============================


you can convert a series to a list
['C', '8/1/2014', '30000', '28960', 'N']
<class 'list'>


you can convert a dataframe to a nested list
[['A', '1/1/2014', '1000', '4000', 'Y'], ['A', '2/1/2014', '12000', '10000', 'Y'], ['A', '3/1/2014', '36000', '2000', 'Y'], ['B', '4/1/2014', '15000', '10000', 'N'], ['B', '4/1/2014', '12000', '11500', 'N'], ['B', '4/1/2014', '90000', '11000', 'N'], ['C', '7/1/2014', '22000', '18000', 'N'], ['C', '8/1/2014', '30000', '28960', 'N'], ['C', '9/1/2014', '53000', '51200', 'N']]
<class 'list'>

the content of a dataframe can be accessed as a numpy.ndarray
[['A' '1/1/2014' '1000' '4000' 'Y']
 ['A' '2/1/2014' '12000' '10000' 'Y']
 ['A' '3/1/2014' '36000' '2000' 'Y']
 ['B' '4/1/2014' '15000' '10000' 'N']
 ['B' '4/1/2014' '12000' '11500' 'N']
 ['B' '4/1/2014' '90000' '11000' 'N']
 ['C' '7/1/2014' '22000' '18000' 'N']
 ['C' '8/1/2014' '30000' '28960' 'N']
 ['C' '9/1/2014' '53000' '51200' 'N']]
<class 'numpy.ndarray'>

codice:

# prefix ser refers to pd.Series object
# prefix df refers to pd.DataFrame object
# prefix lst refers to list object

import pandas as pd
import numpy as np

df=pd.DataFrame([
        ['A',   '1/1/2014',    '1000',    '4000',    'Y'],
        ['A',   '2/1/2014',    '12000',   '10000',   'Y'],
        ['A',   '3/1/2014',    '36000',   '2000',    'Y'],
        ['B',   '4/1/2014',    '15000',   '10000',   'N'],
        ['B',   '4/1/2014',    '12000',   '11500',   'N'],
        ['B',   '4/1/2014',    '90000',   '11000',   'N'],
        ['C',   '7/1/2014',    '22000',   '18000',   'N'],
        ['C',   '8/1/2014',    '30000',   '28960',   'N'],
        ['C',   '9/1/2014',    '53000',   '51200',   'N']
        ], columns=['cluster', 'load_date',   'budget',  'actual',  'fixed_price'])
print('df',df, sep='\n', end='\n\n')

ser_aggCol=df.aggregate(lambda x: [x.tolist()], axis=0).map(lambda x:x[0])
print('ser_aggCol (collapse each column to a list)',ser_aggCol, sep='\n', end='\n\n\n')

ser_aggRows=pd.Series(df.values.tolist()) 
print('ser_aggRows (collapse each row to a list)',ser_aggRows, sep='\n', end='\n\n\n')

df_gr=df.groupby('cluster').agg(lambda x: list(x))
print('df_gr (here you get lists for each cluster)',df_gr, sep='\n', end='\n\n\n')

lst_dfFiltGr=[ df.loc[df['cluster']==val,:] for val in df['cluster'].unique() ]
print('a list of separate dataframes for each cluster', sep='\n', end='\n\n')
for dfTmp in lst_dfFiltGr:
    print('df for cluster '+str(dfTmp.loc[dfTmp.index[0],'cluster']),dfTmp, sep='\n', end='\n\n')

ser_singleColLD=df.loc[:,'load_date']
print('just the values of column load_date',ser_singleColLD, sep='\n', end='\n\n\n')

ser_singleCol2=df.iloc[:,2]
print('just the values of column number 2',ser_singleCol2, sep='\n', end='\n\n\n')

ser_singleRow7=df.iloc[7,:]
print('just the values of row number 7',ser_singleRow7, sep='\n', end='\n\n\n')

print('='*30+' JUST FOR COMPLETENESS '+'='*30, end='\n\n\n')

lst_fromSer=ser_singleRow7.tolist()
print('you can convert a series to a list',lst_fromSer, type(lst_fromSer), sep='\n', end='\n\n\n')

lst_fromDf=df.values.tolist()
print('you can convert a dataframe to a nested list',lst_fromDf, type(lst_fromDf), sep='\n', end='\n\n')

arr_fromDf=df.values
print('the content of a dataframe can be accessed as a numpy.ndarray',arr_fromDf, type(arr_fromDf), sep='\n', end='\n\n')

come sottolineato da cs95, altri metodi dovrebbero essere preferiti rispetto .valuesall'attributo panda dalla versione 0.24 di panda, vedi qui . Lo uso qui, perché la maggior parte delle persone (entro il 2019) avrà ancora una versione precedente, che non supporta i nuovi consigli. Puoi controllare la tua versione conprint(pd.__version__)


1

Se la tua colonna avrà un solo valore, qualcosa del genere pd.series.tolist()produrrà un errore. Per garantire che funzioni in tutti i casi, utilizzare il codice seguente:

(
    df
        .filter(['column_name'])
        .values
        .reshape(1, -1)
        .ravel()
        .tolist()
)

-1

Supponendo che il nome del frame di dati dopo aver letto il foglio Excel sia df, prendere un elenco vuoto (ad es. dataList), Scorrere il frame di dati riga per riga e aggiungere all'elenco vuoto come-

dataList = [] #empty list
for index, row in df.iterrows(): 
    mylist = [row.cluster, row.load_date, row.budget, row.actual, row.fixed_price]
    dataList.append(mylist)

O,

dataList = [] #empty list
for row in df.itertuples(): 
    mylist = [row.cluster, row.load_date, row.budget, row.actual, row.fixed_price]
    dataList.append(mylist)

No, se si stampa il dataList, si otterrà ogni riga come un elenco nel dataList.


I nomi delle variabili e delle funzioni dovrebbero seguire lo lower_case_with_underscoresstile. Che vantaggio ha esattamente questa soluzione rispetto a quelle esistenti? Inoltre, scoraggio davvero l'uso dell'accesso in stile attributo su Series e DataFrames.
AMC

-1
 amount = list()
    for col in df.columns:
        val = list(df[col])
        for v in val:
            amount.append(v)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.