দুটি পান্ডার কলামের স্ট্রিং কনটেনটেশন


90

আমার একটি নিম্নলিখিত আছে DataFrame:

from pandas import *
df = DataFrame({'foo':['a','b','c'], 'bar':[1, 2, 3]})

দেখে মনে হচ্ছে:

    bar foo
0    1   a
1    2   b
2    3   c

এখন আমি এর মতো কিছু পেতে চাই:

     bar
0    1 is a
1    2 is b
2    3 is c

আমি কীভাবে এটি অর্জন করতে পারি? আমি নিম্নলিখিত চেষ্টা করেছিলাম:

df['foo'] = '%s is %s' % (df['bar'], df['foo'])

তবে এটি আমাকে একটি ভুল ফলাফল দেয়:

>>>print df.ix[0]

bar                                                    a
foo    0    a
1    b
2    c
Name: bar is 0    1
1    2
2
Name: 0

বোবা প্রশ্নের জন্য দুঃখিত, তবে এই একটি পান্ডাস: একটি ডেটা ফ্রেমে দুটি কলাম একত্রিত করা আমার পক্ষে সহায়ক ছিল না।

উত্তর:



71

এই প্রশ্নের ইতিমধ্যে উত্তর দেওয়া হয়েছে, তবে আমি বিশ্বাস করি যে পূর্বে আলোচিত নয় এমন কিছু দরকারী পদ্ধতির মিশ্রণে ফেলে দেওয়া এবং পারফর্মেন্সের দিক থেকে প্রস্তাবিত সমস্ত পদ্ধতির তুলনা করা ভাল হবে।

কর্মক্ষমতা ক্রমবর্ধমান ক্রমে এই সমস্যার কয়েকটি কার্যকর সমাধান এখানে দেওয়া হল are


DataFrame.agg

এটি একটি সহজ- str.formatভিত্তিক পদ্ধতির।

df['baz'] = df.agg('{0[bar]} is {0[foo]}'.format, axis=1)
df
  foo  bar     baz
0   a    1  1 is a
1   b    2  2 is b
2   c    3  3 is c

আপনি এখানে এফ স্ট্রিং বিন্যাস ব্যবহার করতে পারেন:

df['baz'] = df.agg(lambda x: f"{x['bar']} is {x['foo']}", axis=1)
df
  foo  bar     baz
0   a    1  1 is a
1   b    2  2 is b
2   c    3  3 is c

char.arrayভিত্তিক কনটেনটেশন

কলামগুলিকে রূপান্তর করতে রূপান্তর করুন chararrays, তারপরে তাদের একসাথে যুক্ত করুন।

a = np.char.array(df['bar'].values)
b = np.char.array(df['foo'].values)

df['baz'] = (a + b' is ' + b).astype(str)
df
  foo  bar     baz
0   a    1  1 is a
1   b    2  2 is b
2   c    3  3 is c

তালিকা বোঝার সঙ্গেzip

পান্ডে আন্ডাররেটেড তালিকা বোঝার কীভাবে হয় তা আমি বড় করে দেখতে পারি না।

df['baz'] = [str(x) + ' is ' + y for x, y in zip(df['bar'], df['foo'])]

বিকল্পভাবে, str.joinকনক্যাট ব্যবহার করে (আরও ভাল স্কেল হবে):

df['baz'] = [
    ' '.join([str(x), 'is', y]) for x, y in zip(df['bar'], df['foo'])]

df
  foo  bar     baz
0   a    1  1 is a
1   b    2  2 is b
2   c    3  3 is c

স্ট্রিং ম্যানিপুলেশনে তালিকা বোধগম্যতা অর্জন করে, কারণ স্ট্রিং অপারেশনগুলি ভেক্টরাইজ করা সহজাতভাবে শক্ত, এবং বেশিরভাগ পান্ডা "ভেক্টরাইজড" ফাংশনগুলি মূলত লুপগুলির চারপাশে মোড়ানো হয়। প্যান্ডাস সহ লুপগুলির জন্য আমি এই বিষয়টি সম্পর্কে ব্যাপকভাবে লিখেছি - কখন আমার যত্ন নেওয়া উচিত? । সাধারণভাবে, যদি আপনাকে সূচী প্রান্তিককরণ সম্পর্কে চিন্তা করতে না হয় তবে স্ট্রিং এবং রেজেক্স ক্রিয়াকলাপগুলির সাথে কাজ করার সময় একটি তালিকা বোধগম্যতা ব্যবহার করুন।

ডিফল্টরূপে উপরে উল্লিখিত তালিকাটি NaN গুলি পরিচালনা করে না। যাইহোক, আপনি সর্বদা একটি চেষ্টা মোড়ানো একটি ফাংশন লিখতে পারে - যদি আপনার এটি পরিচালনা করার প্রয়োজন হয় তবে।

def try_concat(x, y):
    try:
        return str(x) + ' is ' + y
    except (ValueError, TypeError):
        return np.nan


df['baz'] = [try_concat(x, y) for x, y in zip(df['bar'], df['foo'])]

perfplot পারফরম্যান্স পরিমাপ

এখানে চিত্র বর্ণনা লিখুন

পারফ্লোট ব্যবহার করে গ্রাফ উত্পন্ন হয়েছিল । এখানে সম্পূর্ণ কোড তালিকা

কার্যাদি

def brenbarn(df):
    return df.assign(baz=df.bar.map(str) + " is " + df.foo)

def danielvelkov(df):
    return df.assign(baz=df.apply(
        lambda x:'%s is %s' % (x['bar'],x['foo']),axis=1))

def chrimuelle(df):
    return df.assign(
        baz=df['bar'].astype(str).str.cat(df['foo'].values, sep=' is '))

def vladimiryashin(df):
    return df.assign(baz=df.astype(str).apply(lambda x: ' is '.join(x), axis=1))

def erickfis(df):
    return df.assign(
        baz=df.apply(lambda x: f"{x['bar']} is {x['foo']}", axis=1))

def cs1_format(df):
    return df.assign(baz=df.agg('{0[bar]} is {0[foo]}'.format, axis=1))

def cs1_fstrings(df):
    return df.assign(baz=df.agg(lambda x: f"{x['bar']} is {x['foo']}", axis=1))

def cs2(df):
    a = np.char.array(df['bar'].values)
    b = np.char.array(df['foo'].values)

    return df.assign(baz=(a + b' is ' + b).astype(str))

def cs3(df):
    return df.assign(
        baz=[str(x) + ' is ' + y for x, y in zip(df['bar'], df['foo'])])

4
আমি সবসময়ই পান্ডে স্ট্রিং কনটেক্সটেশন সম্পর্কে জানতে চেয়েছিলাম, তবে খুব জিজ্ঞাসা করতেও খুব ভয় পেল!
ইয়ানস

আপনি কি প্লটটি পরবর্তী স্তরের 10 4 (বা আরও উচ্চতর) তে আপডেট করতে পারবেন , বর্তমান প্লট 10% (আজকের শর্তের জন্য খুব ছোট) এর মধ্যে সীমাবদ্ধ সহ একটি চাক্ষুষ উত্তরটি হ'ল সিএস 3 সেরা, অবশেষে আপনি যখন দেখবেন ব্রেনবার্ন সিএস 3 এর চেয়ে কম ক্ষতিকারক খুঁজছেন, তাই সম্ভবত বড় ডেটাসেটের জন্য ব্রেইনবার্নই সেরা (দ্রুত) উত্তর।
ভেলিজার ভেসেলিনোভ

4
পুনঃটুইট করেছেন আমার যেটা অবাক করে তা হ'ল তালিকার কমপ এবং পান্ডস কনটেনটেশন উভয়ের চেয়ে অদ্ভুত সংমিশ্রণটি ধীর।
cs95

4
আপনি ব্যবহার df['bar'].tolist()এবং df['foo'].tolist()মধ্যে বিবেচনা করেছেন cs3()? আমার অনুমান যে এটি "বেস" সময়টি সামান্য বাড়িয়ে তুলবে তবে এটি আরও ভাল স্কেল হবে।
ছায়াছবির

44

আপনার কোডের সমস্যাটি হ'ল আপনি প্রতিটি সারিতে অপারেশন প্রয়োগ করতে চান। আপনি এটি যেভাবে লিখেছেন তা পুরো 'বার' এবং 'ফু' কলামগুলিকে গ্রহণ করে, সেগুলিকে স্ট্রিংয়ে রূপান্তরিত করে এবং আপনাকে একটি বড় স্ট্রিং ফিরিয়ে দেয়। আপনি এটি লিখতে পারেন:

df.apply(lambda x:'%s is %s' % (x['bar'],x['foo']),axis=1)

এটি অন্য উত্তরের চেয়ে লম্বা তবে আরও জেনেরিক (স্ট্রিং নয় এমন মানগুলির সাথে ব্যবহার করা যেতে পারে)।


13

আপনি ব্যবহার করতে পারে

df['bar'] = df['bar'].str.cat(df['foo'].values.astype(str), sep=' is ')

4
এটি কার্যকর হয় না যেহেতু df ['বার'] কোনও স্ট্রিং কলাম নয়। সঠিক অ্যাসাইনমেন্টটি হ'ল df['bar'] = df['bar'].astype(str).str.cat(df['foo'], sep=' is ')
সিবিএনআরআর

8
df.astype(str).apply(lambda x: ' is '.join(x), axis=1)

0    1 is a
1    2 is b
2    3 is c
dtype: object

এই উত্তরটি নির্ধারিত সংখ্যক কলাম (> 1) ও নির্ধারিত কলামের নামগুলির সাথেও কাজ করে, এটি অন্যান্যটির চেয়ে আরও দরকারী করে তোলে।
জনডাঙ্গার

5

series.str.cat এই সমস্যার কাছে যাওয়ার সবচেয়ে নমনীয় উপায়:

জন্য df = pd.DataFrame({'foo':['a','b','c'], 'bar':[1, 2, 3]})

df.foo.str.cat(df.bar.astype(str), sep=' is ')

>>>  0    a is 1
     1    b is 2
     2    c is 3
     Name: foo, dtype: object

বা

df.bar.astype(str).str.cat(df.foo, sep=' is ')

>>>  0    1 is a
     1    2 is b
     2    3 is c
     Name: bar, dtype: object

সর্বাধিক গুরুত্বপূর্ণ (এবং বিপরীতে .join()), এটি আপনাকে প্যারামিটার Nullসহ মানগুলি উপেক্ষা বা প্রতিস্থাপন করতে দেয় allowsna_rep


কেন এই কার্যকারিতা .join()আমাকে বিভ্রান্ত করে না
জনড্যাঞ্জার

4

@ ড্যানিয়েলভেলকভ উত্তরটি হ'ল স্ট্রিং লিটারাল ব্যবহারের পক্ষে সঠিক একটি তবে দ্রুত:

# Daniel's
%timeit df.apply(lambda x:'%s is %s' % (x['bar'],x['foo']),axis=1)
## 963 µs ± 157 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# String literals - python 3
%timeit df.apply(lambda x: f"{x['bar']} is {x['foo']}", axis=1)
## 849 µs ± 4.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.