Эквивалент Paste R на Python

Я новый аффинион python. Для пользователей R существует одна функция: вставка, которая помогает объединить две или более переменных в фреймворке данных. Это очень полезно. Например предположим, что у меня есть этот фреймворк данных:

   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 

Я хочу создать новый столбец, который будет использовать другой столбец в фрейме данных и некотором тексте. С R я делаю:

> 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
   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

Мой вопрос: как я могу сделать то же самое в Python Pandas или другом модуле?

Спасибо заранее, Лучший, GJT

--- > Что я пробовал Ну, я очень новый. Извините за мою ошибку. Я пытаюсь воспроизвести пример в Python, и мы полагаем, что я получаю что-то вроде этого

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

Я пробовал это в основном

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

И я получил это

    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

Теперь, я полагаю, что я должен зацикливаться с условием, если в R?

нет векторизации, например,

Ответ 1

Вот простая реализация, которая работает над списками и, возможно, другими итерами. Предупреждение: оно было слегка проверено и только в 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'

Вы также можете немного веселиться и реплицировать другие функции, такие как paste0:

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

Ответ 2

В этом конкретном случае оператор paste в R ближе всего к Python format, который был добавлен в Python 2.6. Он более новый и несколько более гибкий, чем более старый оператор %.

Для чисто Python-ic ответа без использования numpy или pandas, вот один из способов сделать это, используя исходные данные в виде списка списков (это также можно было бы сделать как список dict, но это казалось мне более сумасшедшим).

# -*- 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)

В результате получится следующее:

[['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']]

Обратите внимание, что, хотя я определил список names, он фактически не используется. Можно было определить словарь с именами названий в качестве ключа и номером поля (начиная с 0) в качестве значения, но я не беспокоился об этом, чтобы попытаться сохранить простой пример.

Функции prix и msg довольно просты. Единственная сложная часть - это понимание списка [m.append(msg(m)) for m in records], которое выполняет итерацию по всем записям и изменяет каждый, чтобы добавить новое поле, созданное с помощью вызова msg.

Ответ 3

мой anwser свободно основан на исходном вопросе, был отредактирован из ответа на слова. Я хотел бы проиллюстрировать моменты:

  • Вставка - оператор% в python
  • с помощью применения вы можете внести новое значение и назначить его новому столбцу

для R-людей: нет ifelse в прямой форме (но есть способы его хорошо заменить).

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

Ответ 4

Давайте попробуем все с применением.

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

вы получите вещи, похожие на пасту

Ответ 5

  1. 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. Или просто 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. patsy может быть уместным (не опытный пользователь сам.)

Ответ 6

Это простой пример того, как добиться этого (если я не хочу, что вы хотите сделать):

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)

Вывод:

>>>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

Этот цикл для печати:   2013-01-01 00:00:00 Постоянное обновление → -0.400550121168, следующие данные -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

Ответ 7

Спасибо всем, Для этого. Я особенно благодарю lowtech. Что хорошо работает:

def apply_to_row(x):
    ret = "Evenement Permanent -->%s à %s à partir de %f euros" % (x['titre'], x['lieu'],x['tarifMin'])
    if x['tarifMin'] != -1.0 :
        ret = "Evenement Permanent -->%s à %s sans prix indiqué" % (x['titre'], x['lieu'])
    return ret;
tt['theColumnIWant'] = tt.apply(apply_to_row, axis = 1)
tt

Что дает

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

Ответ 8

Вы можете просто использовать +. Например, вместо paste0(x, y, z) в R вы должны использовать x + y + z в Python.

Ответ 9

Это очень похоже на команду Paste в R: R-код:

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

[1]

"Здесь | Я | хочу | к | конкатенация | слова | с использованием | труба | разделитель"

Python:

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

Результат:

'Здесь | Я | хочу | к | конкатенация | слова | с использованием | труба | разделитель'

Ответ 10

Если вы хотите просто вставить два строковых столбца вместе, вы можете упростить ответ @shouldsee, потому что вам не нужно создавать функцию. Например, в моем случае:

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

Для этого может потребоваться, чтобы обе серии имели object dtype (я не проверял).