รวมสองคอลัมน์ของข้อความใน dataframe ใน pandas / python


487

ฉันมี dataframe 20 x 4000 ใน Python โดยใช้แพนด้า สองคอลัมน์เหล่านี้จะถูกตั้งชื่อและYear quarterฉันต้องการที่จะสร้างตัวแปรที่เรียกว่าperiodทำให้Year = 2000และเข้าquarter= q22000q2

มีใครสามารถช่วยได้บ้าง

คำตอบ:


530

หากทั้งสองคอลัมน์เป็นสตริงคุณสามารถต่อกันได้โดยตรง:

df["period"] = df["Year"] + df["quarter"]

หากหนึ่ง (หรือทั้งสอง) ของคอลัมน์ไม่ได้เป็นสตริงที่พิมพ์คุณควรแปลงมัน (พวกเขา) ก่อน

df["period"] = df["Year"].astype(str) + df["quarter"]

ระวังของ NaN เมื่อทำสิ่งนี้!


หากคุณต้องการเข้าร่วมหลายคอลัมน์สตริงคุณสามารถใช้agg:

df['period'] = df[['Year', 'quarter', ...]].agg('-'.join, axis=1)

โดยที่ "-" เป็นตัวคั่น


13
เป็นไปได้หรือไม่ที่จะเพิ่มหลายคอลัมน์เข้าด้วยกันโดยไม่ต้องพิมพ์คอลัมน์ทั้งหมด? สมมติว่าadd(dataframe.iloc[:, 0:10])เป็นตัวอย่าง?
ไฮเซนเบิร์ก

5
@Heisenberg sumที่ควรจะเป็นไปได้ด้วยในตัวงูหลาม
silvado

6
@Silvado คุณช่วยยกตัวอย่างการเพิ่มหลายคอลัมน์ได้ไหม? ขอบคุณ
c1c1c1

6
ระวังคุณต้องใช้แผนที่ (str) กับทุกคอลัมน์ที่ไม่ได้อยู่ในตำแหน่งแรก ถ้าไตรมาสเป็นตัวเลขคุณจะทำ dataframe["period"] = dataframe["Year"].map(str) + dataframe["quarter"].map(str)แผนที่เพียงแค่ใช้การแปลงสตริงกับรายการทั้งหมด
Ozgur Ozturk

13
วิธีการแก้ปัญหานี้สามารถสร้างปัญหาได้หากคุณมีค่าน่านระวัง

269
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
df['period'] = df[['Year', 'quarter']].apply(lambda x: ''.join(x), axis=1)

ให้ผลกับดาต้าเฟรมนี้

   Year quarter  period
0  2014      q1  2014q1
1  2015      q2  2015q2

วิธีนี้ทำให้จำนวนคอลัมน์สตริงเป็นแบบทั่วไปโดยแทนที่df[['Year', 'quarter']]ด้วยส่วนแบ่งคอลัมน์ใด ๆ ของ dataframe ของคุณเช่นdf.iloc[:,0:2].apply(lambda x: ''.join(x), axis=1)ของคุณเช่น

คุณสามารถตรวจสอบข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสมัคร () ได้ที่นี่


20
lambda x: ''.join(x)เป็นเพียง''.joinไม่
DSM

6
@OzgurOzturk: ​​ประเด็นคือส่วนแลมบ์ดาของการlambda x: ''.join(x)ก่อสร้างไม่ได้ทำอะไรเลย มันก็เหมือนใช้แทนเพียงlambda x: sum(x) sum
DSM

4
ได้รับการยืนยันผลเดียวกันเมื่อใช้คือ:''.join df['period'] = df[['Year', 'quarter']].apply(''.join, axis=1)
Max Ghenis

1
@Archie joinใช้strอินสแตนซ์ในการวนซ้ำเท่านั้น ใช้mapการแปลงพวกเขาทั้งหมดลงแล้วใช้str join
John Strood

16
'-'. เข้าร่วม (x.map (str))
Manjul

257

ชุดข้อมูลขนาดเล็ก (<150rows)

[''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]

หรือช้ากว่าเล็กน้อย แต่กะทัดรัดกว่า:

df.Year.str.cat(df.quarter)

ชุดข้อมูลที่ใหญ่ขึ้น (> 150rows)

df['Year'].astype(str) + df['quarter']

UPDATE:กราฟเวลา Pandas 0.23.4

ป้อนคำอธิบายรูปภาพที่นี่

ลองทดสอบด้วยแถว 200K DF:

In [250]: df
Out[250]:
   Year quarter
0  2014      q1
1  2015      q2

In [251]: df = pd.concat([df] * 10**5)

In [252]: df.shape
Out[252]: (200000, 2)

อัปเดต:กำหนดเวลาใหม่โดยใช้ Pandas 0.19.0

การจับเวลาโดยไม่มีการเพิ่มประสิทธิภาพ CPU / GPU (เรียงลำดับจากเร็วไปช้า):

In [107]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 131 ms per loop

In [106]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 161 ms per loop

In [108]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 189 ms per loop

In [109]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 567 ms per loop

In [110]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 584 ms per loop

In [111]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 24.7 s per loop

เวลาโดยใช้การเพิ่มประสิทธิภาพ CPU / GPU:

In [113]: %timeit df['Year'].astype(str) + df['quarter']
10 loops, best of 3: 53.3 ms per loop

In [114]: %timeit df['Year'].map(str) + df['quarter']
10 loops, best of 3: 65.5 ms per loop

In [115]: %timeit df.Year.str.cat(df.quarter)
10 loops, best of 3: 79.9 ms per loop

In [116]: %timeit df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop

In [117]: %timeit df[['Year','quarter']].astype(str).sum(axis=1)
1 loop, best of 3: 230 ms per loop

In [118]: %timeit df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
1 loop, best of 3: 9.38 s per loop

ตอบผลงานโดย @ anton-vbr


เวลาของคุณแตกต่างกันอย่างไรระหว่าง 261 ถึง 264
Anton Protopopov

@AntonProtopopov เห็นได้ชัด 100ms จากที่ไหนเลย :)
Dennis Golomazov

@AntonProtopopov ฉันเดาว่ามันเป็นส่วนผสมของการกำหนดเวลาสองครั้ง - อันที่หนึ่งใช้การเพิ่มประสิทธิภาพ CPU / GPU อีกอันหนึ่งไม่ได้ ฉันได้อัปเดตคำตอบแล้วตั้งเวลาไว้ที่นั่น ...
MaxU

การใช้. suum () นี้ล้มเหลวหากคอลัมน์ทั้งหมดดูเหมือนว่าอาจเป็นจำนวนเต็ม (เช่นรูปแบบสตริงของจำนวนเต็ม) แต่ดูเหมือนว่าแพนด้าจะแปลงกลับเป็นตัวเลขก่อนที่จะสรุป!
CPBL

@CPBL ลองใช้วิธีนี้:df.T.apply(lambda x: x.str.cat(sep=''))
MaxU

157

วิธีการcat()ของ.straccessor ใช้งานได้ดีในเรื่องนี้:

>>> import pandas as pd
>>> df = pd.DataFrame([["2014", "q1"], 
...                    ["2015", "q3"]],
...                   columns=('Year', 'Quarter'))
>>> print(df)
   Year Quarter
0  2014      q1
1  2015      q3
>>> df['Period'] = df.Year.str.cat(df.Quarter)
>>> print(df)
   Year Quarter  Period
0  2014      q1  2014q1
1  2015      q3  2015q3

cat() แม้อนุญาตให้คุณเพิ่มตัวคั่นได้ตัวอย่างเช่นสมมติว่าคุณมีจำนวนเต็มสำหรับปีและช่วงเวลาเท่านั้นคุณสามารถทำได้:

>>> import pandas as pd
>>> df = pd.DataFrame([[2014, 1],
...                    [2015, 3]],
...                   columns=('Year', 'Quarter'))
>>> print(df)
   Year Quarter
0  2014       1
1  2015       3
>>> df['Period'] = df.Year.astype(str).str.cat(df.Quarter.astype(str), sep='q')
>>> print(df)
   Year Quarter  Period
0  2014       1  2014q1
1  2015       3  2015q3

การเข้าร่วมหลายคอลัมน์เป็นเพียงเรื่องของการส่งรายการชุดข้อมูลหรือ dataframe ที่มีทั้งหมด แต่คอลัมน์แรกเป็นพารามิเตอร์ที่จะstr.cat()เรียกใช้ในคอลัมน์แรก (ชุดข้อมูล):

>>> df = pd.DataFrame(
...     [['USA', 'Nevada', 'Las Vegas'],
...      ['Brazil', 'Pernambuco', 'Recife']],
...     columns=['Country', 'State', 'City'],
... )
>>> df['AllTogether'] = df['Country'].str.cat(df[['State', 'City']], sep=' - ')
>>> print(df)
  Country       State       City                   AllTogether
0     USA      Nevada  Las Vegas      USA - Nevada - Las Vegas
1  Brazil  Pernambuco     Recife  Brazil - Pernambuco - Recife

โปรดทราบว่าหากแพนด้า dataframe / series ของคุณมีค่า Null คุณจะต้องรวมพารามิเตอร์ na_rep เพื่อแทนที่ค่า NaN ด้วยสตริงมิฉะนั้นคอลัมน์ที่รวมกันจะเริ่มต้นเป็น NaN


12
นี้ดูเหมือนว่าวิธีที่ดีกว่า (อาจจะมีประสิทธิภาพมากขึ้นด้วย) กว่าlambdaหรือmap; มันก็แค่อ่านอย่างหมดจดที่สุด
dwanderson

1
@ZakS โดยผ่านคอลัมน์ที่เหลือเป็น dataframe str.cat()แทนของซีรีส์เป็นพารามิเตอร์แรกจะเป็น ฉันจะแก้ไขคำตอบ
LeoRochael

คุณใช้แพนด้าเวอร์ชันไหน ฉันได้รับ ValueError: คุณหมายถึงsepคำสำคัญหรือไม่? ใน pandas-0.23.4 ขอบคุณ!
Qinqing Liu

@QinqingLiu ฉันลองเหล่านี้อีกครั้งด้วย pandas-0.23.4 และดูเหมือนว่าจะทำงาน sepพารามิเตอร์เป็นสิ่งจำเป็นเท่านั้นถ้าคุณตั้งใจจะแยกส่วนของการตัดแบ่งสตริง หากคุณได้รับข้อผิดพลาดโปรดแสดงตัวอย่างความล้มเหลวของคุณให้เราทราบ
LeoRochael

31

การใช้ฟังก์ชั่น lamba ครั้งนี้กับ string.format ()

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': ['q1', 'q2']})
print df
df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)
print df

  Quarter  Year
0      q1  2014
1      q2  2015
  Quarter  Year YearQuarter
0      q1  2014      2014q1
1      q2  2015      2015q2

สิ่งนี้ช่วยให้คุณทำงานกับค่าที่ไม่ใช่สตริงและฟอร์แมตใหม่ได้ตามต้องการ

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'Quarter': [1, 2]})
print df.dtypes
print df

df['YearQuarter'] = df[['Year','Quarter']].apply(lambda x : '{}q{}'.format(x[0],x[1]), axis=1)
print df

Quarter     int64
Year       object
dtype: object
   Quarter  Year
0        1  2014
1        2  2015
   Quarter  Year YearQuarter
0        1  2014      2014q1
1        2  2015      2015q2

1
เร็วกว่ามาก: .apply (''. เข้าร่วม (x), Axis = 1)
Ghanem

19

คำตอบง่ายๆสำหรับคำถามของคุณ

    year    quarter
0   2000    q1
1   2000    q2

> df['year_quarter'] = df['year'] + '' + df['quarter']

> print(df['year_quarter'])
  2000q1
  2000q2

3
จะล้มเหลวหากYearไม่ใช่สตริง
geher

4
ใช้df['Year'].astype(str) + '' + df['quarter'].astype(str)
Yedhrab

2
อะไรคือประเด็นของการแก้ปัญหานี้เพราะมันเหมือนกับคำตอบสูงสุด?
AMC

14

ถึงแม้ว่าคำตอบ @silvado เป็นสิ่งที่ดีถ้าคุณเปลี่ยนdf.map(str)ไปdf.astype(str)มันจะเร็วขึ้น:

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})

In [131]: %timeit df["Year"].map(str)
10000 loops, best of 3: 132 us per loop

In [132]: %timeit df["Year"].astype(str)
10000 loops, best of 3: 82.2 us per loop

12

ขอให้เราคิดว่าคุณ dataframeมีที่dfมีคอลัมน์และYearQuarter

import pandas as pd
df = pd.DataFrame({'Quarter':'q1 q2 q3 q4'.split(), 'Year':'2000'})

สมมติว่าเราต้องการดูดาต้าเฟรม

df
>>>  Quarter    Year
   0    q1      2000
   1    q2      2000
   2    q3      2000
   3    q4      2000

สุดท้ายเชื่อมต่อYearและQuarterดังต่อไปนี้

df['Period'] = df['Year'] + ' ' + df['Quarter']

ตอนนี้คุณสามารถprint df ดู dataframe ที่ได้

df
>>>  Quarter    Year    Period
    0   q1      2000    2000 q1
    1   q2      2000    2000 q2
    2   q3      2000    2000 q3
    3   q4      2000    2000 q4

หากคุณไม่ต้องการให้มีช่องว่างระหว่างปีกับไตรมาสเพียงแค่ลบออกโดยทำ

df['Period'] = df['Year'] + df['Quarter']

3
ระบุเป็นสตริงdf['Period'] = df['Year'].map(str) + df['Quarter'].map(str)
Stuber

ฉันได้รับTypeError: Series cannot perform the operation +เมื่อใช้อย่างใดอย่างหนึ่งหรือdf2['filename'] = df2['job_number'] + '.' + df2['task_number'] df2['filename'] = df2['job_number'].map(str) + '.' + df2['task_number'].map(str)
คาร์ลเบเกอร์

อย่างไรก็ตามdf2['filename'] = df2['job_number'].astype(str) + '.' + df2['task_number'].astype(str)ทำงานได้ดี
Karl Baker

@KarlBaker ฉันคิดว่าคุณไม่มีสายอักขระในอินพุตของคุณ แต่ฉันดีใจที่คุณคิดออก หากคุณดูตัวอย่างdataframeที่ฉันสร้างไว้ด้านบนคุณจะเห็นว่าคอลัมน์ทั้งหมดเป็นstringของ
Samuel Nde

อะไรคือประเด็นของการแก้ปัญหานี้เพราะมันเหมือนกับคำตอบสูงสุด?
AMC

10

นี่คือการใช้งานที่ฉันพบว่าหลากหลายมาก:

In [1]: import pandas as pd 

In [2]: df = pd.DataFrame([[0, 'the', 'quick', 'brown'],
   ...:                    [1, 'fox', 'jumps', 'over'], 
   ...:                    [2, 'the', 'lazy', 'dog']],
   ...:                   columns=['c0', 'c1', 'c2', 'c3'])

In [3]: def str_join(df, sep, *cols):
   ...:     from functools import reduce
   ...:     return reduce(lambda x, y: x.astype(str).str.cat(y.astype(str), sep=sep), 
   ...:                   [df[col] for col in cols])
   ...: 

In [4]: df['cat'] = str_join(df, '-', 'c0', 'c1', 'c2', 'c3')

In [5]: df
Out[5]: 
   c0   c1     c2     c3                cat
0   0  the  quick  brown  0-the-quick-brown
1   1  fox  jumps   over   1-fox-jumps-over
2   2  the   lazy    dog     2-the-lazy-dog

FYI: วิธีนี้ใช้งานได้ดีกับ Python 3 แต่ทำให้ฉันมีปัญหาใน Python 2
Alex P. Miller

10

เมื่อข้อมูลของคุณถูกแทรกลงใน dataframe คำสั่งนี้ควรแก้ปัญหาของคุณ:

df['period'] = df[['Year', 'quarter']].apply(lambda x: ' '.join(x.astype(str)), axis=1)

คำตอบนี้เป็นเหมือนกันกับผู้ที่มีอายุมากกว่าที่นิยมมากขึ้นอย่างใดอย่างหนึ่ง
AMC

9

มีประสิทธิภาพมากขึ้นคือ

def concat_df_str1(df):
    """ run time: 1.3416s """
    return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index)

และนี่คือการทดสอบเวลา:

import numpy as np
import pandas as pd

from time import time


def concat_df_str1(df):
    """ run time: 1.3416s """
    return pd.Series([''.join(row.astype(str)) for row in df.values], index=df.index)


def concat_df_str2(df):
    """ run time: 5.2758s """
    return df.astype(str).sum(axis=1)


def concat_df_str3(df):
    """ run time: 5.0076s """
    df = df.astype(str)
    return df[0] + df[1] + df[2] + df[3] + df[4] + \
           df[5] + df[6] + df[7] + df[8] + df[9]


def concat_df_str4(df):
    """ run time: 7.8624s """
    return df.astype(str).apply(lambda x: ''.join(x), axis=1)


def main():
    df = pd.DataFrame(np.zeros(1000000).reshape(100000, 10))
    df = df.astype(int)

    time1 = time()
    df_en = concat_df_str4(df)
    print('run time: %.4fs' % (time() - time1))
    print(df_en.head(10))


if __name__ == '__main__':
    main()

ขั้นสุดท้ายเมื่อใช้sum(concat_df_str2) ผลลัพธ์จะไม่เพียงแค่ concat มันจะเปลี่ยนเป็นจำนวนเต็ม


1 การแก้ปัญหาเรียบร้อยนี้ยังช่วยให้เราสามารถระบุคอลัมน์: เช่นหรือdf.values[:, 0:3] df.values[:, [0,2]]
หิมะตอม่อ

9

การสรุปเป็นหลายคอลัมน์ทำไมไม่:

columns = ['whatever', 'columns', 'you', 'choose']
df['period'] = df[columns].astype(str).sum(axis=1)

ดูดี แต่ถ้าฉันต้องการเพิ่มตัวคั่นระหว่างสตริงเช่น '-'
Odisseo

@Odisseo ดูคำตอบนี้stackoverflow.com/questions/19377969/…
geher

6

การใช้zipอาจเร็วกว่า:

df["period"] = [''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]

กราฟ:

ป้อนคำอธิบายรูปภาพที่นี่

import pandas as pd
import numpy as np
import timeit
import matplotlib.pyplot as plt
from collections import defaultdict

df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})

myfuncs = {
"df['Year'].astype(str) + df['quarter']":
    lambda: df['Year'].astype(str) + df['quarter'],
"df['Year'].map(str) + df['quarter']":
    lambda: df['Year'].map(str) + df['quarter'],
"df.Year.str.cat(df.quarter)":
    lambda: df.Year.str.cat(df.quarter),
"df.loc[:, ['Year','quarter']].astype(str).sum(axis=1)":
    lambda: df.loc[:, ['Year','quarter']].astype(str).sum(axis=1),
"df[['Year','quarter']].astype(str).sum(axis=1)":
    lambda: df[['Year','quarter']].astype(str).sum(axis=1),
    "df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1)":
    lambda: df[['Year','quarter']].apply(lambda x : '{}{}'.format(x[0],x[1]), axis=1),
    "[''.join(i) for i in zip(dataframe['Year'].map(str),dataframe['quarter'])]":
    lambda: [''.join(i) for i in zip(df["Year"].map(str),df["quarter"])]
}

d = defaultdict(dict)
step = 10
cont = True
while cont:
    lendf = len(df); print(lendf)
    for k,v in myfuncs.items():
        iters = 1
        t = 0
        while t < 0.2:
            ts = timeit.repeat(v, number=iters, repeat=3)
            t = min(ts)
            iters *= 10
        d[k][lendf] = t/iters
        if t > 2: cont = False
    df = pd.concat([df]*step)

pd.DataFrame(d).plot().legend(loc='upper center', bbox_to_anchor=(0.5, -0.15))
plt.yscale('log'); plt.xscale('log'); plt.ylabel('seconds'); plt.xlabel('df rows')
plt.show()

6

วิธีที่ง่ายที่สุด:

โซลูชันทั่วไป

df['combined_col'] = df[['col1', 'col2']].astype(str).apply('-'.join, axis=1)

การแก้ปัญหาเฉพาะคำถาม

df['quarter_year'] = df[['quarter', 'year']].astype(str).apply(''.join, axis=1)

ระบุตัวคั่นที่ต้องการภายในเครื่องหมายคำพูดก่อน. join



5

โซลูชันนี้ใช้ขั้นตอนกลางที่บีบอัดสองคอลัมน์ของ DataFrame ไปยังคอลัมน์เดียวที่มีรายการค่า สิ่งนี้ใช้ได้กับสตริงเท่านั้น แต่สำหรับคอลัมน์ -type ทุกชนิด

import pandas as pd
df = pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']})
df['list']=df[['Year','quarter']].values.tolist()
df['period']=df['list'].apply(''.join)
print(df)

ผลลัพธ์:

   Year quarter        list  period
0  2014      q1  [2014, q1]  2014q1
1  2015      q2  [2015, q2]  2015q2

ดูเหมือนว่าคนอื่นจะไม่ทำงาน ฉันได้รับ TypeError: ลำดับรายการ 1: อินสแตนซ์ str ที่คาดไว้, พบโฟล
Prometheus

ใช้สตริงแรกกับสตริง การดำเนินการเข้าร่วมใช้งานได้เฉพาะสำหรับสตริง
Markus Dutschke

โซลูชันนี้จะไม่ทำงานเพื่อรวมสองคอลัมน์เข้ากับ dtype ที่แตกต่างกันดูคำตอบของฉันสำหรับวิธีแก้ปัญหาที่ถูกต้องสำหรับกรณีดังกล่าว
Will Will

2

ดังที่หลายคนได้กล่าวถึงก่อนหน้านี้คุณต้องแปลงแต่ละคอลัมน์เป็นสตริงแล้วใช้ตัวดำเนินการบวกเพื่อรวมคอลัมน์สตริงสองคอลัมน์ คุณสามารถเพิ่มประสิทธิภาพได้อย่างมากโดยใช้ NumPy

%timeit df['Year'].values.astype(str) + df.quarter
71.1 ms ± 3.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df['Year'].astype(str) + df['quarter']
565 ms ± 22.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

ฉันต้องการที่จะใช้รุ่น numpyified แต่ฉันได้รับข้อผิดพลาด: การป้อนข้อมูล : df2['filename'] = df2['job_number'].values.astype(str) + '.' + df2['task_number'].values.astype(str)-> เอาท์พุทTypeError: ufunc 'add' did not contain a loop with signature matching types dtype('<U21') dtype('<U21') dtype('<U21') : ทั้ง job_number และ task_number เป็น ints
Karl Baker

นั่นเป็นเพราะคุณกำลังรวมสองอาร์เรย์ numpy มันใช้งานได้ถ้าคุณรวมอาเรย์ numpy เข้ากับ pandas ซีรี่ย์ asdf['Year'].values.astype(str) + df.quarter
AbdulRehmanLiaqat

2

ฉันคิดว่าวิธีที่ดีที่สุดในการรวมคอลัมน์ในแพนด้าคือการแปลงทั้งคอลัมน์เป็นจำนวนเต็มแล้วเปลี่ยนเป็น str

df[['Year', 'quarter']] = df[['Year', 'quarter']].astype(int).astype(str)
df['Period']= df['Year'] + 'q' + df['quarter']

การแปลงทั้งสองคอลัมน์เป็นจำนวนเต็มทำไมแปลงเป็น int ก่อน เมื่อคุณลบสิ่งแปลกประหลาดนั้นทางออกนี้จะเหมือนกับคำตอบยอดนิยมปัจจุบัน
AMC

2

นี่คือบทสรุปของฉันของโซลูชันด้านบนเพื่อต่อ / รวมสองคอลัมน์เข้ากับค่า int และ str ในคอลัมน์ใหม่โดยใช้ตัวคั่นระหว่างค่าของคอลัมน์ โซลูชันสามตัวทำงานเพื่อจุดประสงค์นี้

# be cautious about the separator, some symbols may cause "SyntaxError: EOL while scanning string literal".
# e.g. ";;" as separator would raise the SyntaxError

separator = "&&" 

# pd.Series.str.cat() method does not work to concatenate / combine two columns with int value and str value. This would raise "AttributeError: Can only use .cat accessor with a 'category' dtype"

df["period"] = df["Year"].map(str) + separator + df["quarter"]
df["period"] = df[['Year','quarter']].apply(lambda x : '{} && {}'.format(x[0],x[1]), axis=1)
df["period"] = df.apply(lambda x: f'{x["Year"]} && {x["quarter"]}', axis=1)

ขอบคุณ! วิธีแก้ปัญหา f-string ของคุณคือสิ่งที่ฉันหวังว่าจะได้ !!!
leerssej

1

.combine_firstใช้

df['Period'] = df['Year'].combine_first(df['Quarter'])

สิ่งนี้ไม่ถูกต้อง .combine_firstจะส่งผลทั้งในค่าจาก'Year'ถูกเก็บไว้ใน'Period'หรือถ้ามันเป็น Null 'Quarter'ค่าจาก 'Period'มันจะไม่เชื่อมสองสตริงและเก็บไว้ใน
Steve G

นี่ผิดพลาด
AMC

0
def madd(x):
    """Performs element-wise string concatenation with multiple input arrays.

    Args:
        x: iterable of np.array.

    Returns: np.array.
    """
    for i, arr in enumerate(x):
        if type(arr.item(0)) is not str:
            x[i] = x[i].astype(str)
    return reduce(np.core.defchararray.add, x)

ตัวอย่างเช่น:

data = list(zip([2000]*4, ['q1', 'q2', 'q3', 'q4']))
df = pd.DataFrame(data=data, columns=['Year', 'quarter'])
df['period'] = madd([df[col].values for col in ['Year', 'quarter']])

df

    Year    quarter period
0   2000    q1  2000q1
1   2000    q2  2000q2
2   2000    q3  2000q3
3   2000    q4  2000q4

0

หนึ่งสามารถใช้วิธีการมอบหมายของDataFrame :

df= (pd.DataFrame({'Year': ['2014', '2015'], 'quarter': ['q1', 'q2']}).
  assign(period=lambda x: x.Year+x.quarter ))

-1
dataframe["period"] = dataframe["Year"].astype(str).add(dataframe["quarter"])

หรือถ้าค่าเป็น [2000] [4] และต้องการสร้าง [2000q4]

dataframe["period"] = dataframe["Year"].astype(str).add('q').add(dataframe["quarter"]).astype(str)

แทน.astype(str)ด้วย.map(str)งานเกินไป


นี่เป็นหลักเหมือนกับคำตอบที่ดีที่สุด
AMC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.