dataframe unire determinati valori

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
sverdrup
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 607
Iscrizione: giovedì 15 giugno 2006, 12:51

dataframe unire determinati valori

Messaggio da sverdrup »

Buongiorno a tutti, ho un dataframe con alcuni valori ad esempio:

id data aggiornamento provincia comune val1 val2 val3 val 4 tot

il mio problema è che in alcuni casi ho delle righe dove ho lo stesso id, ma i valori relativi ai comuni sono diversi. Io vorrei fare in modo che nel dataframe in questi casi si raggruppassero i valori relativi ai comuni e si sommassero i valori di val1, val2, val3 ... e tot, mentre la data, l'aggiornamento e la provincia rimanessero invariati.
ex:

01001 31/10/2022 31/10/2022 Roma bracciano 10 3 4 56 73
01001 31/10/2022 31/10/2022 Roma castel gandolfo 2 11 7 0 19

devo ottenere:

01001 31/10/2022 31/10/2022 Roma bracciano, castel gandolfo 12 14 11 56 93

mentre nei casi in cui l'id sia univoco deve lasciare tutto invariato.
ho provato con:
test = df_ba.groupby(['id','data','aggiornamento','provincia','comune']).agg(lambda x : x.sum() if x.dtype=='float64' else ' '.join(x))
ma non va, qualcuno ha qualche idea,
grazie
"Not everything that counts can be counted, and not everything that can be counted counts."
korda
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1703
Iscrizione: giovedì 24 dicembre 2020, 15:58

Re: dataframe unire determinati valori

Messaggio da korda »

Mi sembra di intuire che il linguaggio sia R, ma sono parecchio arrugginito su di esso: potresti dare conferma e/o specificare di quale linguaggio stiamo parlando?
Io non sono Bagheera né Akela, io non frequento la Rupe.
Io sono Kaa: faccio ballare le scimmie alle Tane Fredde.
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: dataframe unire determinati valori

Messaggio da nuzzopippo »

korda ha scritto:
mercoledì 9 novembre 2022, 17:04
Mi sembra di intuire che il linguaggio sia R, ma sono parecchio arrugginito su di esso: potresti dare conferma e/o specificare di quale linguaggio stiamo parlando?
Non conosco R ma quella funzione "lambda" mi fa pensare a python, supposto sia giusto :

Non conosco minimamente pandas (non mi occorso sin ora) ma leggendo la documentazione su groupby e su agg si arguisce che può anche eseguirsi un certo numero di "azioni" specificando per colonna, delle semplici prove mi hanno permesso di ottenere un "qualcosa" che può essere utile:

Codice: Seleziona tutto

d = [['01001', '31/10/2022', 'Roma', 'Bracciano', 10, 3, 4, 56, 73],
     ['01002', '31/10/2022', 'Viterbo', 'Tarquinia', 7, 2, 2, 51, 69],
     ['01001', '31/10/2022', 'Roma', 'Castel Gandolfo', 2, 11, 7, 0, 19],
     ['01003', '31/10/2022', 'Latina', 'Bassiano', 3, 7, 5, 1, 4]]
c = ['id', 'data', 'provincia', 'comune', 'val1', 'val2', 'val3', 'val4', 'val5']
df = pd.DataFrame(d, columns=c)
print(df)
      id        data provincia           comune  val1  val2  val3  val4  val5
0  01001  31/10/2022      Roma        Bracciano    10     3     4    56    73
1  01002  31/10/2022   Viterbo        Tarquinia     7     2     2    51    69
2  01001  31/10/2022      Roma  Castel Gandolfo     2    11     7     0    19
3  01003  31/10/2022    Latina         Bassiano     3     7     5     1     4
test = df.groupby(['id','data','provincia']).agg({'comune': list,
                                                  'val1': 'sum',
                                                  'val2': 'sum',
                                                  'val3': 'sum',
                                                  'val4': 'sum',
                                                  'val5': 'sum'})
print(test)
                                                  comune  val1  ...  val4  val5
id    data       provincia                                      ...            
01001 31/10/2022 Roma       [Bracciano, Castel Gandolfo]    12  ...    56    92
01002 31/10/2022 Viterbo                     [Tarquinia]     7  ...    51    69
01003 31/10/2022 Latina                       [Bassiano]     3  ...     1     4

[3 rows x 6 columns]
da notare che invece di indicare una lista per la colonna "comune" può essere indicato il parametro "str" che restituirà una stringa, che però avrà un '\n' finale, incasinando eventuali istruzioni print ... purtroppo non mi è riuscito di inserire funzioni proprie per trattare la stringa.

Spero possa essere utile
:ciao:
Fatti non foste a viver come bruti ...
Avatar utente
DoctorStrange
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2854
Iscrizione: mercoledì 14 ottobre 2015, 9:33
Desktop: Gnome3
Distribuzione: Ubuntu 22.04 LTS Jammy Jellyfish
Sesso: Maschile
Località: Roma, Italia

Re: dataframe unire determinati valori

Messaggio da DoctorStrange »

Dico anche la mia. Visto che parli di dataframe, si parla di Apache Spark? Quello potrebbe essere uno statement in SparkQL?

Io invece lo fare in scala. Un'iterazione Map-Reduce ti toglierebbe dai guai. Ad esempio, in scala:

Codice: Seleziona tutto

val out : RDD[(String, Int)] = df_ba.map(item => (item.split(" ")(3).toString.toLowerCase,1)).reduceByKey((iteratore : Int, accumulatore : Int) => (iteratore + accumulatore);
Io ho usato gli RDD, ma se tu vuoi usare i dataframe, lo puoi fare con sintassi affine.
Ultima modifica di DoctorStrange il giovedì 10 novembre 2022, 20:45, modificato 1 volta in totale.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: dataframe unire determinati valori

Messaggio da gila75 »

Io mapperei l'id: finche' trovi caratteri che non sono lettere. Raccogli in 2 stringhe:
Confrontale, sono uguali?
No---> mantieni 2 stringhe differenti
Si---> scansiona oltre fino a raccogliere citta'.
Concateni le 2 stringhe citta' e concateni all'id.
Ora vai oltre, raccogli numeri finali, che pero' sono stringhe.
Converti in int atoi (in c) o cast in python se non erro, sommi e riconverti in str e concateni ancora.
Ovviamente parto dal presupposto che tutte le stringe siano fatte come da tuo esempio.
Non credo sia difficile.

Se poi id, lunghezze varie sono costanti tutto e' ancora più agevole. Quello non lo hai specificato ma è importante

EDIT: rettifico, non è così semplice come sembra. Processare stringhe è sempre ostico: gestire casi particolari,
estrarre porzioni dopo uno spazio ma solo e se dopo c'è x cosa, insomma ci si può impantanare in mille casi.
Credo che senza funzioni specifiche, non so per esempio espressioni regolari, si vada a scrivere un codice macchinoso.
Tempo fa per gestire gli infiniti casi che in una stringa puoi avere mi ero affidato agli automi a stati finiti, che credo in definitiva
girino sotto il cofano delle espressioni regolari.
Comunque per mio esercizio ci sto provando, vediamo se esce qualcosa di decente...
Ultima modifica di gila75 il lunedì 14 novembre 2022, 6:10, modificato 1 volta in totale.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: dataframe unire determinati valori

Messaggio da gila75 »

Come temevo si va a finire in un mappazzone (come dice Barbieri) senza strumenti un po' evoluti di parsing delle stringhe.

Va bhe. Io ho scritto così, ci sono alcune limitazioni con gli spazi, ma se si rispettano come da stringa iniziale, dovrebbe funzionare.

Mappazzone come dicevo ma il parsing è sempre ostico. Magari in python si migliora un po' ma con strumenti base credo non di molto:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int s_posto;

void test_1(char s[],char tmp[]);
void test_luoghi(char s[],char tmp[],char new[],int *l);
void cerca_numeri (char s1[],int array1[],int l1);
void somma (char new[],int array1[], int array2[]);


// sommo i due numeri delle stringhe memorizzati in 2 array
// poi converto di nuovo in str e concateno a nuova stringa
void somma (char new[],int array1[], int array2[])
{
	int i,sum;
	char tmp[10];
	for (i=0; i<5; i++)
	{
		sum=array1[i]+array2[i];
		sprintf(tmp, "%d", sum);
		strcat(new," ");
		strcat(new,tmp);
	}
}
		

// l1 ha tenuto traccia dove finiva nella stringa la località
// da li in poi spezzo con strtok, converto in int
void cerca_numeri (char s1[],int array1[],int l1)
{
	int i=0;
	const char s[2] = " ";
	char *token=s1;
	token = strtok(&s1[l1], s);
   
	while( token != NULL ) 
	{
		array1[i]=atoi(token);
		i++;
    	token = strtok(NULL, s);
	}
	 
}


// raccoglie la località.
// termina quando incontra il primo carattere numero
void test_luoghi(char s[],char tmp[],char new[],int *l)
{
	int i;
	int x=0;
	i=s_posto;
	while (1)
	{
		if (isdigit (s[i])==0)
		{
			tmp[x]=s[i];
			i++;x++;
		}

		else 
		{
			tmp[x]='\0';
			break;
		}
		
	}
	*l=i;
	strcat (new,tmp);
}
	
	
// scansiona id iniziale
// finisce quando trova il primo carattere (R) di Roma
void test_1(char s[],char tmp[])
{
	
	
	int i=0;
	while (1)
	{
		if (isalpha (s[i])==0)
		{
			tmp[i]=s[i];
			i++;
		}

		else 
		{
			tmp[i]='\0';
			break;
		}
		
	}
	s_posto=i;
}
	


int main(void)
{


	char s1[]="01001 31/10/2022 31/10/2022 Roma bracciano 10 3 4 56 73";
    char s2[]="01001 31/10/2022 31/10/2022 Roma castel gandolfo 2 11 7 0 19";  
	char new[128];
	char tmp_s1[64];
	char tmp_s2[64];
	int array1[5];
	int array2[5];
	int l1,l2;

	test_1(s1,tmp_s1);
	test_1(s2,tmp_s2);

	if (strcmp(tmp_s1,tmp_s2)!=0)
	{
		puts("ID diversi, mantengo stringhe iniziali");
		printf("%s\n",s1);
		printf("%s\n",s2);
		return 0;
	}
	strcat(new,tmp_s1);
	test_luoghi(s1,tmp_s1,new,&l1);
	new[strlen(new)-1]=',';
	test_luoghi(s2,tmp_s2,new,&l2);
	cerca_numeri (s1,array1,l1);
	cerca_numeri (s2,array2,l2);
	somma (new,array1,array2);
	puts ("STRINGA RISULTANTE: ");
	printf ("%s\n", new);
  	return 0;


}




output:

Codice: Seleziona tutto

gila@gila-pc:~/Scrivania$ ./xx
STRINGA RISULTANTE: 
01001 31/10/2022 31/10/2022 Roma bracciano,Roma castel gandolfo  12 14 11 56 92
gila@gila-pc:~/Scrivania$ 

Io ho scritto un programma, ma non so dove opera l'utente ecc, quindi potrebbe risultare completamente inutile
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 10 ospiti