python r pandas paste

Equivalente de Pasta R a Python



pandas paste (8)

Soy un nuevo aficionado a los pitones. Para los usuarios de R, hay una función: pegar que ayuda a concatenar dos o más variables en un marco de datos. Es muy útil. Por ejemplo, supongamos que tengo este marco de datos:

categorie titre tarifMin lieu long lat img dateSortie 1 zoo, Aquar 0.0 Aquar 2.385 48.89 ilo,0 2 zoo, Aquar 4.5 Aquar 2.408 48.83 ilo,0 6 lieu Jardi 0.0 Jardi 2.320 48.86 ilo,0 7 lieu Bois 0.0 Bois 2.455 48.82 ilo,0 13 espac Canal 0.0 Canal 2.366 48.87 ilo,0 14 espac Canal -1.0 Canal 2.384 48.89 ilo,0 15 parc Le Ma 20.0 Le Ma 2.353 48.87 ilo,0

Quiero crear una nueva columna que use otra columna en un marco de datos y un texto. Con R, hago:

> y$thecolThatIWant=ifelse(y$tarifMin!=-1, + paste("Evenement permanent -->",y$categorie, + y$titre,"C partir de",y$tarifMin,"€uros"), + paste("Evenement permanent -->",y$categorie, + y$titre,"sans prix indique"))

Y el resultado es:

> y categorie titre tarifMin lieu long lat img dateSortie 1 zoo, Aquar 0.0 Aquar 2.385 48.89 ilo,0 2 zoo, Aquar 4.5 Aquar 2.408 48.83 ilo,0 6 lieu Jardi 0.0 Jardi 2.320 48.86 ilo,0 7 lieu Bois 0.0 Bois 2.455 48.82 ilo,0 13 espac Canal 0.0 Canal 2.366 48.87 ilo,0 14 espac Canal -1.0 Canal 2.384 48.89 ilo,0 15 parc Le Ma 20.0 Le Ma 2.353 48.87 ilo,0 thecolThatIWant 1 Evenement permanent --> zoo, Aquar C partir de 0.0 €uros 2 Evenement permanent --> zoo, Aquar C partir de 4.5 €uros 6 Evenement permanent --> lieu Jardi C partir de 0.0 €uros 7 Evenement permanent --> lieu Bois C partir de 0.0 €uros 13 Evenement permanent --> espac Canal C partir de 0.0 €uros 14 Evenement permanent --> espac Canal C partir de -1.0 €uros 15 Evenement permanent --> parc Le Ma C partir de 20.0 €uros

Mi pregunta es: ¿Cómo puedo hacer lo mismo en Python Pandas o en algún otro módulo?

Lo que he intentado hasta ahora: bueno, soy un usuario muy nuevo. Lo siento mucho por mi error. Intento replicar el ejemplo en Python y suponemos que obtengo algo como esto

table=pd.read_csv("y.csv",sep=",") tt= table.loc[:,[''categorie'',''titre'',''tarifMin'',''long'',''lat'',''lieu'']] table ategorie titre tarifMin long lat lieu 0 zoo, Aquar 0.0 2.385 48.89 Aquar 1 zoo, Aquar 4.5 2.408 48.83 Aquar 2 lieu Jardi 0.0 2.320 48.86 Jardi 3 lieu Bois 0.0 2.455 48.82 Bois 4 espac Canal 0.0 2.366 48.87 Canal 5 espac Canal -1.0 2.384 48.89 Canal 6 parc Le Ma 20.0 2.353 48.87 Le Ma

Yo intenté esto básicamente

sc="Even permanent -->" + " "+ tt.titre+" "+tt.lieu tt[''theColThatIWant''] = sc tt

Y tengo esto

categorie titre tarifMin long lat lieu theColThatIWant 0 zoo, Aquar 0.0 2.385 48.89 Aquar Even permanent --> Aquar Aquar 1 zoo, Aquar 4.5 2.408 48.83 Aquar Even permanent --> Aquar Aquar 2 lieu Jardi 0.0 2.320 48.86 Jardi Even permanent --> Jardi Jardi 3 lieu Bois 0.0 2.455 48.82 Bois Even permanent --> Bois Bois 4 espac Canal 0.0 2.366 48.87 Canal Even permanent --> Canal Canal 5 espac Canal -1.0 2.384 48.89 Canal Even permanent --> Canal Canal 6 parc Le Ma 20.0 2.353 48.87 Le Ma Even permanent --> Le Ma Le Ma

Ahora, supongo que tengo que hacer un bucle con la condición si no hay vectorización como en R?


  1. Puedes probar pandas.Series.str.cat

    import pandas as pd def paste0(ss,sep=None,na_rep=None,): ''''''Analogy to R paste0'''''' ss = [pd.Series(s) for s in ss] ss = [s.astype(str) for s in ss] s = ss[0] res = s.str.cat(ss[1:],sep=sep,na_rep=na_rep) return res pasteA=paste0

  2. O simplemente sep.join()

    #

    def paste0(ss,sep=None,na_rep=None, castF=unicode, ##### many languages dont work well with str ): if sep is None: sep='''' res = [castF(sep).join(castF(s) for s in x) for x in zip(*ss)] return res pasteB = paste0 %timeit pasteA([range(1000),range(1000,0,-1)],sep=''_'') # 100 loops, best of 3: 7.11 ms per loop %timeit pasteB([range(1000),range(1000,0,-1)],sep=''_'') # 100 loops, best of 3: 2.24 ms per loop

  3. Lo he usado para imitar el reciclaje.

    import itertools def paste0(ss,sep=None,na_rep=None,castF=unicode): ''''''Analogy to R paste0 '''''' if sep is None: sep=u'''' L = max([len(e) for e in ss]) it = itertools.izip(*[itertools.cycle(e) for e in ss]) res = [castF(sep).join(castF(s) for s in next(it) ) for i in range(L)] # res = pd.Series(res) return res

  4. patsy puede ser relevante (no soy un usuario experimentado).


Aquí hay una implementación simple que funciona en listas, y probablemente otros iterables. Advertencia: solo se ha probado ligeramente, y solo en Python 3.5:

import functools def reduce_concat(x, sep=""): return functools.reduce(lambda x, y: str(x) + sep + str(y), x) def paste(*lists, sep=" ", collapse=None): result = map(lambda x: reduce_concat(x, sep=sep), zip(*lists)) if collapse is not None: return reduce_concat(result, sep=collapse) return list(result) print(paste([1,2,3], [11,12,13], sep='','')) print(paste([1,2,3], [11,12,13], sep='','', collapse=";")) # [''1,11'', ''2,12'', ''3,13''] # ''1,11;2,12;3,13''

También puedes divertirte más y replicar otras funciones como paste0 :

paste0 = functools.partial(paste, sep="")


Este es un ejemplo simple de cómo lograrlo (si no estoy desgastado, ¿qué desea hacer?):

import numpy as np import pandas as pd dates = pd.date_range(''20130101'',periods=6) df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list(''ABCD'')) for row in df.itertuples(): index, A, B, C, D = row print ''%s Evenement permanent --> %s , next data %s'' % (index, A, B)

Salida:

>>>df A B C D 2013-01-01 -0.400550 -0.204032 -0.954237 0.019025 2013-01-02 0.509040 -0.611699 1.065862 0.034486 2013-01-03 0.366230 0.805068 -0.144129 -0.912942 2013-01-04 1.381278 -1.783794 0.835435 -0.140371 2013-01-05 1.140866 2.755003 -0.940519 -2.425671 2013-01-06 -0.610569 -0.282952 0.111293 -0.108521

Esto que bucle para imprimir: 2013-01-01 00:00:00 Evenement permanente -> -0.400550121168, datos siguientes -0.204032344442

2013-01-02 00:00:00 Evenement permanent --> 0.509040318928 , next data -0.611698560541 2013-01-03 00:00:00 Evenement permanent --> 0.366230438863 , next data 0.805067758304 2013-01-04 00:00:00 Evenement permanent --> 1.38127775713 , next data -1.78379439485 2013-01-05 00:00:00 Evenement permanent --> 1.14086631509 , next data 2.75500268167 2013-01-06 00:00:00 Evenement permanent --> -0.610568516983 , next data -0.282952162792


Esto funciona mucho como el comando Pegar en el código R: R:

words = c("Here", "I","want","to","concatenate","words","using","pipe","delimeter") paste(words,collapse="|")

[1]

"Aquí | Quiero | concatenar | palabras | utilizando | pipe | delimeter"

Pitón:

words = ["Here", "I","want","to","concatenate","words","using","pipe","delimeter"] "|".join(words)

Resultado:

''Aquí | Quiero | concatenar | palabras | usando | pipe | delimeter''


Para este caso particular, el operador de paste en R es el más cercano al format de Python que se agregó en Python 2.6. Es más nuevo y algo más flexible que el operador % anterior.

Para una respuesta puramente Python-ic sin usar números o pandas, aquí hay una forma de hacerlo usando sus datos originales en forma de una lista de listas (esto también podría haberse hecho como una lista de dict, pero eso parecía más desordenado a mi).

# -*- coding: utf-8 -*- names=[''categorie'',''titre'',''tarifMin'',''lieu'',''long'',''lat'',''img'',''dateSortie''] records=[[ ''zoo'', ''Aquar'', 0.0,''Aquar'',2.385,48.89,''ilo'',0],[ ''zoo'', ''Aquar'', 4.5,''Aquar'',2.408,48.83,''ilo'',0],[ ''lieu'', ''Jardi'', 0.0,''Jardi'',2.320,48.86,''ilo'',0],[ ''lieu'', ''Bois'', 0.0,''Bois'', 2.455,48.82,''ilo'',0],[ ''espac'', ''Canal'', 0.0,''Canal'',2.366,48.87,''ilo'',0],[ ''espac'', ''Canal'', -1.0,''Canal'',2.384,48.89,''ilo'',0],[ ''parc'', ''Le Ma'', 20.0,''Le Ma'', 2.353,48.87,''ilo'',0] ] def prix(p): if (p != -1): return ''C partir de {} €uros''.format(p) return ''sans prix indique'' def msg(a): return ''Evenement permanent --> {}, {} {}''.format(a[0],a[1],prix(a[2])) [m.append(msg(m)) for m in records] from pprint import pprint pprint(records)

El resultado es este:

[[''zoo'', ''Aquar'', 0.0, ''Aquar'', 2.385, 48.89, ''ilo'', 0, ''Evenement permanent --> zoo, Aquar C partir de 0.0 /xe2/x82/xacuros''], [''zoo'', ''Aquar'', 4.5, ''Aquar'', 2.408, 48.83, ''ilo'', 0, ''Evenement permanent --> zoo, Aquar C partir de 4.5 /xe2/x82/xacuros''], [''lieu'', ''Jardi'', 0.0, ''Jardi'', 2.32, 48.86, ''ilo'', 0, ''Evenement permanent --> lieu, Jardi C partir de 0.0 /xe2/x82/xacuros''], [''lieu'', ''Bois'', 0.0, ''Bois'', 2.455, 48.82, ''ilo'', 0, ''Evenement permanent --> lieu, Bois C partir de 0.0 /xe2/x82/xacuros''], [''espac'', ''Canal'', 0.0, ''Canal'', 2.366, 48.87, ''ilo'', 0, ''Evenement permanent --> espac, Canal C partir de 0.0 /xe2/x82/xacuros''], [''espac'', ''Canal'', -1.0, ''Canal'', 2.384, 48.89, ''ilo'', 0, ''Evenement permanent --> espac, Canal sans prix indique''], [''parc'', ''Le Ma'', 20.0, ''Le Ma'', 2.353, 48.87, ''ilo'', 0, ''Evenement permanent --> parc, Le Ma C partir de 20.0 /xe2/x82/xacuros'']]

Tenga en cuenta que aunque he definido una lista de names en realidad no se utiliza. Uno podría definir un diccionario con los nombres de los títulos como clave y el número de campo (comenzando desde 0) como valor, pero no me molesté en esto para tratar de mantener el ejemplo simple.

Las funciones prix y msg son bastante simples. La única parte difícil es la comprensión de la lista [m.append(msg(m)) for m in records] que se repite en todos los registros y modifica cada uno para agregar su nuevo campo, creado mediante una llamada a msg .


Probemos cosas con aplique.

df.apply( lambda x: str( x.loc[ desired_col ] ) + "pasting?" , axis = 1 )

Recibirá cosas similares como pasta


Si solo desea pegar dos columnas de cadena, puede simplificar la respuesta de @ shouldsee porque no necesita crear la función. Por ejemplo, en mi caso:

df[''newcol''] = df[''id_part_one''].str.cat(df[''id_part_two''], sep=''_'')

Podría ser necesario que ambas Series sean de object dtype para esto (no he verificado).


mi respuesta está basada libremente en la pregunta original, fue editada de la respuesta por woles. Me gustaría ilustrar los puntos:

  • pegar es% operador en python
  • Usando Apply puedes hacer un nuevo valor y asignarlo a una nueva columna.

para la gente de R: no hay ifelse en forma directa (pero hay maneras de reemplazarlo muy bien).

import numpy as np import pandas as pd dates = pd.date_range(''20140412'',periods=7) df = pd.DataFrame(np.random.randn(7,4),index=dates,columns=list(''ABCD'')) df[''categorie''] = [''z'', ''z'', ''l'', ''l'', ''e'', ''e'', ''p''] def apply_to_row(x): ret = "this is the value i want: %f" % x[''A''] if x[''B''] > 0: ret = "no, this one is better: %f" % x[''C''] return ret df[''theColumnIWant''] = df.apply(apply_to_row, axis = 1) print df