পান্ডস একটি সিরিজ / ডেটাফ্রেম কলামের শর্তসাপেক্ষ সৃষ্টি


314

নীচের লাইনের সাথে আমার একটি ডেটাফ্রেম রয়েছে:

    Type       Set
1    A          Z
2    B          Z           
3    B          X
4    C          Y

আমি ডেটাফ্রেমে একই দৈর্ঘ্যের ডেটাফ্রেমে (বা একটি সিরিজ উত্পন্ন করতে) একটি অন্য কলাম যুক্ত করতে চাই (= সমান সংখ্যক রেকর্ড / সারি) যা সেট = 'জেড' হলে একটি বর্ণ সবুজ এবং সেট = অন্যথায় যদি 'লাল' সেট করে থাকে ।

এটি করার সর্বোত্তম উপায় কী?

উত্তর:


709

আপনার যদি কেবল দুটি পছন্দ থেকে নির্বাচন করতে হয়:

df['color'] = np.where(df['Set']=='Z', 'green', 'red')

উদাহরণ স্বরূপ,

import pandas as pd
import numpy as np

df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
df['color'] = np.where(df['Set']=='Z', 'green', 'red')
print(df)

উৎপাদনের

  Set Type  color
0   Z    A  green
1   Z    B  green
2   X    B    red
3   Y    C    red

আপনার যদি দুটিরও বেশি শর্ত থাকে তবে ব্যবহার করুনnp.select । উদাহরণস্বরূপ, যদি আপনি চান তাহলে colorহতে

  • yellow কখন (df['Set'] == 'Z') & (df['Type'] == 'A')
  • অন্যথায় blueযখন(df['Set'] == 'Z') & (df['Type'] == 'B')
  • অন্যথায় purpleযখন(df['Type'] == 'B')
  • অন্যথায় black,

তারপরে ব্যবহার করুন

df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
conditions = [
    (df['Set'] == 'Z') & (df['Type'] == 'A'),
    (df['Set'] == 'Z') & (df['Type'] == 'B'),
    (df['Type'] == 'B')]
choices = ['yellow', 'blue', 'purple']
df['color'] = np.select(conditions, choices, default='black')
print(df)

যা ফলন দেয়

  Set Type   color
0   Z    A  yellow
1   Z    B    blue
2   X    B  purple
3   Y    C   black

1
যদি আমি দুই অবস্থার ভিতরে রাখা কাজ করে না যেখানে সঙ্গে দফা এবং
অমল শর্মা

2
df ['color'] = list (np.where (df ['সেট'] == 'জেড', 'সবুজ', 'লাল')) পান্ডাদের সতর্কতা দমন করবে: একটি মান একটি অনুলিপিতে সেট করার চেষ্টা করছে একটি ডেটা ফ্রেম থেকে একটি স্লাইস এর। পরিবর্তে .loc [সারি_ইনডেক্সার, কল_ইন্ডেক্সার] = মান ব্যবহার করার চেষ্টা করুন
ডেনসন

3
'সবুজ' এবং 'লাল' কলাম গাণিতিকের সাথেও প্রতিস্থাপন করা যেতে পারে। যেমন ,df['foo'] = np.where(df['Set']=='Z', df['Set'], df['Type'].shift(1))
আলেজান্দ্রো

এনপি.হোয়ার কি নতুন কলাম তৈরি করে? আমি এই কোডটি ব্যবহার করেছি এবং যখন আমি df.color.head করি () আমি পেয়েছি: 'numpy.ndarray' অবজেক্টটির 'মাথা' নেই
ভিভিভি

3
এটা লজ্জাজনক যে আমি এই একাধিকবার উত্সাহ দিতে পারি না। একটি upvote যথেষ্ট মনে হচ্ছে না।
হার্পার

120

শর্তসাপেক্ষে আরেকটি কলাম তৈরি করার জন্য তালিকার বোধগম্যতা way যদি আপনি উদাহরণস্বরূপ কলামগুলিতে অবজেক্ট ডাইটিপসের সাথে কাজ করে থাকেন তবে তালিকা বোধগম্যতা সাধারণত বেশিরভাগ অন্যান্য পদ্ধতিকে ছাড়িয়ে যায়।

উদাহরণ তালিকা অনুধাবন:

df['color'] = ['red' if x == 'Z' else 'green' for x in df['Set']]

% টাইমিট পরীক্ষা:

import pandas as pd
import numpy as np

df = pd.DataFrame({'Type':list('ABBC'), 'Set':list('ZZXY')})
%timeit df['color'] = ['red' if x == 'Z' else 'green' for x in df['Set']]
%timeit df['color'] = np.where(df['Set']=='Z', 'green', 'red')
%timeit df['color'] = df.Set.map( lambda x: 'red' if x == 'Z' else 'green')

1000 loops, best of 3: 239 µs per loop
1000 loops, best of 3: 523 µs per loop
1000 loops, best of 3: 263 µs per loop

4
মনে রাখবেন যে অনেক বড় ডেটাফ্রেম (থিংক-সাইজ pd.DataFrame({'Type':list('ABBC')*100000, 'Set':list('ZZXY')*100000})), numpy.whereআউটপেসগুলি সহ map, তবে তালিকাটি বোঝার বিষয়টি কিং (প্রায় 50% এর চেয়ে দ্রুত numpy.where)।
কৃষ্ণাঙ্গ

3
যদি শর্তটির একাধিক কলাম থেকে তথ্য প্রয়োজন হয় তবে তালিকা বোধগম্য পদ্ধতিটি ব্যবহার করা যেতে পারে? : আমি (এই কাজ করে না) ভালো কিছু খোঁজ করছিdf['color'] = ['red' if (x['Set'] == 'Z') & (x['Type'] == 'B') else 'green' for x in df]
Mappi

2
ডাটাফ্রেমে এটিরোজ যুক্ত করুন, তারপরে আপনি সারিটির মাধ্যমে একাধিক কলামগুলি অ্যাক্সেস করতে পারবেন: ['লাল' যদি (সারি ['সেট'] == 'জেড') এবং (সারি ['প্রকার'] == 'বি') অন্য 'সবুজ 'সূচকের জন্য, সারি সারি ডিএফ.টায়রোজ ()]
চেকইবাস্টার্ড

1
দ্রষ্টব্য, আপনার যদি ডেটা ফ্রেমের অন্য সিরিজ থেকে প্রতিস্থাপনের মানগুলি নেওয়া দরকার তবে এই দুর্দান্ত সমাধানটি কার্যকর হবে নাdf['color_type'] = np.where(df['Set']=='Z', 'green', df['Type'])
পল রাগিগ্যাক্স

@ শেকিবাস্টার্ড বা না করুন, যেহেতু .iterrows()কুখ্যাতিজনকভাবে সুগঠিত এবং ডেটারফ্রেমে পুনরাবৃত্তি করার সময় পরিবর্তন করা উচিত নয়।
এএমসি

21

এটি অর্জন করা যেতে পারে এমন আরও একটি উপায়

df['color'] = df.Set.map( lambda x: 'red' if x == 'Z' else 'green')

ভাল পদ্ধতির, এটি দ্রুত দক্ষতার জন্য স্মরণে নেওয়া যেতে পারে (বড় ডেটাসেটগুলিতে), তবে অতিরিক্ত পদক্ষেপের প্রয়োজন হবে।
ইয়াকভ ব্র্রেসার

21

তালিকার কীগুলিতে নতুন মানচিত্রের মানচিত্র তৈরি করার জন্য একটি অভিধান ব্যবহার করে এই বিড়ালটিকে ত্বকের আরও একটি উপায় দেওয়া হয়েছে:

def map_values(row, values_dict):
    return values_dict[row]

values_dict = {'A': 1, 'B': 2, 'C': 3, 'D': 4}

df = pd.DataFrame({'INDICATOR': ['A', 'B', 'C', 'D'], 'VALUE': [10, 9, 8, 7]})

df['NEW_VALUE'] = df['INDICATOR'].apply(map_values, args = (values_dict,))

এটি দেখতে কেমন দেখাচ্ছে:

df
Out[2]: 
  INDICATOR  VALUE  NEW_VALUE
0         A     10          1
1         B      9          2
2         C      8          3
3         D      7          4

আপনার কাছে অনেকগুলি ifelseটাইপ স্টেটমেন্ট (যেমন প্রতিস্থাপনের জন্য অনেকগুলি অনন্য মান) থাকবে যখন এই পদ্ধতিটি খুব শক্তিশালী হতে পারে ।

এবং অবশ্যই আপনি সর্বদা এটি করতে পারেন:

df['NEW_VALUE'] = df['INDICATOR'].map(values_dict)

তবে applyআমার মেশিনে উপরের পদ্ধতির চেয়ে সেই পদ্ধতির চেয়ে তিনগুণ বেশি ধীর ।

এবং আপনি এটি ব্যবহার করেও করতে পারেন dict.get:

df['NEW_VALUE'] = [values_dict.get(v, None) for v in df['INDICATOR']]

আমি এই উত্তরটি পছন্দ করি কারণ এটি দেখায় যে মানগুলির একাধিক প্রতিস্থাপন কীভাবে করা যায়
মনিকা হেডনেক

তবে আমার মেশিনে উপরে থেকে প্রয়োগের পদ্ধতির চেয়ে সেই পদ্ধতির চেয়ে তিনগুণ বেশি ধীর। আপনি কিভাবে এই মানদণ্ড করেছেন? আমার দ্রুত পরিমাপ থেকে .map()সমাধানটি 10 ​​গুনের চেয়ে 10 গুণ বেশি দ্রুত .apply()
এএমসি

আপডেট: 100,000,000 সারিগুলিতে, 52 টি স্ট্রিংয়ের মানগুলি .apply()47 সেকেন্ড নেয়, কেবল 5.91 সেকেন্ডের তুলনায় .map()
এএমসি

19

এখানে সময় নির্ধারণের চেয়ে নীচেরটি ধীর গতির , তবে আমরা একাধিক কলামের সামগ্রীর উপর ভিত্তি করে অতিরিক্ত কলামটি গণনা করতে পারি এবং অতিরিক্ত কলামের জন্য দুটিরও বেশি মান গণনা করা যায়।

কেবল "সেট" কলামটি ব্যবহার করে সাধারণ উদাহরণ:

def set_color(row):
    if row["Set"] == "Z":
        return "red"
    else:
        return "green"

df = df.assign(color=df.apply(set_color, axis=1))

print(df)
  Set Type  color
0   Z    A    red
1   Z    B    red
2   X    B  green
3   Y    C  green

অ্যাকাউন্টে নেওয়া আরও রঙ এবং আরও কলামগুলির উদাহরণ:

def set_color(row):
    if row["Set"] == "Z":
        return "red"
    elif row["Type"] == "C":
        return "blue"
    else:
        return "green"

df = df.assign(color=df.apply(set_color, axis=1))

print(df)
  Set Type  color
0   Z    A    red
1   Z    B    red
2   X    B  green
3   Y    C   blue

সম্পাদনা (21/06/2019): প্লাইটাটা ব্যবহার করে

এই ধরণের জিনিসগুলি করার জন্য প্লাইটাটা ব্যবহার করাও সম্ভব (এটি ব্যবহারের চেয়েও ধীর বলে মনে হয় assignএবং apply)।

from plydata import define, if_else

সাধারণ if_else:

df = define(df, color=if_else('Set=="Z"', '"red"', '"green"'))

print(df)
  Set Type  color
0   Z    A    red
1   Z    B    red
2   X    B  green
3   Y    C  green

বাসিন্দা if_else:

df = define(df, color=if_else(
    'Set=="Z"',
    '"red"',
    if_else('Type=="C"', '"green"', '"blue"')))

print(df)                            
  Set Type  color
0   Z    A    red
1   Z    B    red
2   X    B   blue
3   Y    C  green

10

পান্ডাদের নতুন আপডেটের মাধ্যমে এটি সম্ভবত সম্ভব হয়েছে, তবে আমি মনে করি যে এখন পর্যন্ত নীচের প্রশ্নের সংক্ষিপ্ত এবং সম্ভবত সেরা উত্তর। আপনি এই .locপদ্ধতিটি ব্যবহার করতে পারেন এবং আপনার প্রয়োজনের উপর নির্ভর করে একটি শর্ত বা কয়েকটি ব্যবহার করতে পারেন।

কোড সংক্ষিপ্তসার:

df=pd.DataFrame(dict(Type='A B B C'.split(), Set='Z Z X Y'.split()))
df['Color'] = "red"
df.loc[(df['Set']=="Z"), 'Color'] = "green"

#practice!
df.loc[(df['Set']=="Z")&(df['Type']=="B")|(df['Type']=="C"), 'Color'] = "purple"

ব্যাখ্যা:

df=pd.DataFrame(dict(Type='A B B C'.split(), Set='Z Z X Y'.split()))

# df so far: 
  Type Set  
0    A   Z 
1    B   Z 
2    B   X 
3    C   Y

একটি 'রঙ' কলাম যুক্ত করুন এবং সমস্ত মানকে "লাল" তে সেট করুন

df['Color'] = "red"

আপনার একক শর্ত প্রয়োগ করুন:

df.loc[(df['Set']=="Z"), 'Color'] = "green"


# df: 
  Type Set  Color
0    A   Z  green
1    B   Z  green
2    B   X    red
3    C   Y    red

বা একাধিক শর্ত যদি আপনি চান:

df.loc[(df['Set']=="Z")&(df['Type']=="B")|(df['Type']=="C"), 'Color'] = "purple"

আপনি পান্ডাস লজিকাল অপারেটর এবং শর্তসাপেক্ষ নির্বাচনের উপর পড়তে পারেন: পান্ডসে বুলিয়ান ইনডেক্সিংয়ের জন্য লজিকাল অপারেটরগুলি


2
এখন পর্যন্ত সেরা এক। আপনি সম্ভবত আরও শর্ত যুক্ত করতে পারেন যে কোডটি হতে পারেdf.loc[(df['Set']=="Z") & (df['Type']=="A"), 'Color'] = "green"
সালভাদোর ভিগো

2
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। প্রকৃতপক্ষে মুশকিল এবং এক্সটেনসেবল।
এএমসি

1

.apply()পদ্ধতি সহ একটি লাইনার নিম্নলিখিত:

df['color'] = df['Set'].apply(lambda set_: 'green' if set_=='Z' else 'red')

এর পরে, dfডেটা ফ্রেমটি এমন দেখাচ্ছে:

>>> print(df)
  Type Set  color
0    A   Z  green
1    B   Z  green
2    B   X    red
3    C   Y    red

0

আপনি যদি বিশাল ডেটা নিয়ে কাজ করছেন তবে একটি মেমোজাইজড পদ্ধতির সেরা হবে:

# First create a dictionary of manually stored values
color_dict = {'Z':'red'}

# Second, build a dictionary of "other" values
color_dict_other = {x:'green' for x in df['Set'].unique() if x not in color_dict.keys()}

# Next, merge the two
color_dict.update(color_dict_other)

# Finally, map it to your column
df['color'] = df['Set'].map(color_dict)

আপনার কাছে বহুবার পুনরাবৃত্তি হওয়া মানগুলি এই পদ্ধতির দ্রুত হবে will আমার সাধারণ থাম্বের নিয়মটি স্মরণ করতে হয় যখন: data_size> 10**4& n_distinct<data_size/4

প্রাক্তন 2,500 বা তার চেয়ে কম স্বতন্ত্র মান সহ 10,000 সারি ক্ষেত্রে স্মৃতিচারণ করুন।


1
এই 2 টিরও বেশি মান সহ কীভাবে কাজ করবে?
এএমসি

ঠিক আছে, সুতরাং মানচিত্রে মাত্র 2 টি পৃথক মান, 100,000,000 সারি সহ, "স্মৃতিচারণ" ছাড়াই চলতে 6.67 সেকেন্ড সময় লাগে এবং এর সাথে 9.86 সেকেন্ড সময় লাগে।
এএমসি

১০,০০,০০,০০০ সারি, ৫২ টি স্বতন্ত্র মান, যেখানে এই মানচিত্রগুলির মধ্যে প্রথম আউটপুট মানের মধ্যে 1 এবং অন্যান্য ৫১ টি অন্যটির সাথে মিলে যায়: স্মৃতিচারণ ছাড়াই 99.৯৯ সেকেন্ড, এর সাথে ১১.১ সেকেন্ড।
এএমসি

আপনার মান কি এলোমেলো ক্রমে? নাকি তারা পিছনে পিছনে? পান্ডাসের উচ্চ গতি @ এমএসি
ইয়াকভ

1
আপনার মান কি এলোমেলো ক্রমে? নাকি তারা পিছনে পিছনে? মানগুলি এলোমেলোভাবে ব্যবহার করে নির্বাচন করা হয় random.choices()
এএমসি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.