পান্ডারা অন্যান্য কলামগুলি থেকে মানগুলির উপর ভিত্তি করে নতুন কলাম তৈরি করে / একাধিক কলামের ক্রম প্রয়োগ করে, সারি অনুসারে


316

আমি (এটি একটি যদি 'অন্য মই ব্যবহার করে) এই ছয় কলাম (আমার কাস্টম ফাংশন প্রয়োগ করতে চান ERI_Hispanic, ERI_AmerInd_AKNatv, ERI_Asian, ERI_Black_Afr.Amer, ERI_HI_PacIsl, ERI_Whiteআমার dataframe প্রতিটি সারিতে)।

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

এটি প্রায় প্রতিটি সারিতে লুপের জন্য করার মতো এবং যদি প্রতিটি রেকর্ড একটি মানদণ্ড পূরণ করে তবে সেগুলিকে একটি তালিকায় যুক্ত করা হয় এবং আসল থেকে বাদ দেওয়া হয়।

নীচের ডেটাফ্রেম থেকে আমার এসকিউএল-তে নিম্নলিখিত বৈশিষ্ট্যের উপর ভিত্তি করে একটি নতুন কলাম গণনা করা প্রয়োজন:

======================== ক্রিটরিয়া ========================= =======

IF [ERI_Hispanic] = 1 THEN RETURN Hispanic
ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN Two or More
ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN A/I AK Native
ELSE IF [ERI_Asian] = 1 THEN RETURN Asian
ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN Black/AA
ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN Haw/Pac Isl.”
ELSE IF [ERI_White] = 1 THEN RETURN White

মন্তব্য: যদি হিস্পানিকের জন্য ইআরআই পতাকাটি সত্য (1) হয় তবে কর্মচারীকে "হিস্পানিক" হিসাবে শ্রেণিবদ্ধ করা হয়

মন্তব্য: যদি 1 টিরও বেশি অ-হিস্পানিক ইআরআই পতাকা সত্য হয়, "দুটি বা তার বেশি" প্রত্যাবর্তন করুন

===================== দ্যাটফরম ============================

     lname          fname       rno_cd  eri_afr_amer    eri_asian   eri_hawaiian    eri_hispanic    eri_nat_amer    eri_white   rno_defined
0    MOST           JEFF        E       0               0           0               0               0               1           White
1    CRUISE         TOM         E       0               0           0               1               0               0           White
2    DEPP           JOHNNY              0               0           0               0               0               1           Unknown
3    DICAP          LEO                 0               0           0               0               0               1           Unknown
4    BRANDO         MARLON      E       0               0           0               0               0               0           White
5    HANKS          TOM         0                       0           0               0               0               1           Unknown
6    DENIRO         ROBERT      E       0               1           0               0               0               1           White
7    PACINO         AL          E       0               0           0               0               0               1           White
8    WILLIAMS       ROBIN       E       0               0           1               0               0               0           White
9    EASTWOOD       CLINT       E       0               0           0               0               0               1           White

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

উত্তর:


407

ঠিক আছে, এর দুটি পদক্ষেপ - প্রথমটি এমন কোনও ফাংশন লিখুন যা আপনি চান অনুবাদটি করে - আমি আপনার সিউডো কোডের ভিত্তিতে একটি উদাহরণ রেখেছি:

def label_race (row):
   if row['eri_hispanic'] == 1 :
      return 'Hispanic'
   if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 :
      return 'Two Or More'
   if row['eri_nat_amer'] == 1 :
      return 'A/I AK Native'
   if row['eri_asian'] == 1:
      return 'Asian'
   if row['eri_afr_amer']  == 1:
      return 'Black/AA'
   if row['eri_hawaiian'] == 1:
      return 'Haw/Pac Isl.'
   if row['eri_white'] == 1:
      return 'White'
   return 'Other'

আপনি এটি অতিক্রম করতে চাইতে পারেন, তবে এটি কৌশলটি মনে হচ্ছে - লক্ষ্য করুন যে ফাংশনটিতে যাওয়া প্যারামিটারটি "সারি" লেবেলযুক্ত একটি সিরিজ অবজেক্ট হিসাবে বিবেচিত হবে।

এর পরে, ফাংশনটি প্রয়োগ করতে পান্ডাস-এ প্রয়োগ ফাংশনটি ব্যবহার করুন - যেমন

df.apply (lambda row: label_race(row), axis=1)

অক্ষটি = 1 নির্দিষ্টকরণকারী নোট করুন, এর অর্থ হল অ্যাপ্লিকেশনটি কলাম স্তরের পরিবর্তে একটি সারিতে করা হয়েছে। ফলাফলগুলি এখানে:

0           White
1        Hispanic
2           White
3           White
4           Other
5           White
6     Two Or More
7           White
8    Haw/Pac Isl.
9           White

যদি আপনি এই ফলাফলগুলি নিয়ে সন্তুষ্ট হন তবে এটি আবার চালাও, ফলাফলগুলি আপনার মূল ডেটাফ্রেমে নতুন কলামে সংরক্ষণ করুন।

df['race_label'] = df.apply (lambda row: label_race(row), axis=1)

ফলস্বরূপ ডেটাফ্রেমটি দেখতে দেখতে (নতুন কলামটি দেখতে ডানদিকে স্ক্রোল করুন):

      lname   fname rno_cd  eri_afr_amer  eri_asian  eri_hawaiian   eri_hispanic  eri_nat_amer  eri_white rno_defined    race_label
0      MOST    JEFF      E             0          0             0              0             0          1       White         White
1    CRUISE     TOM      E             0          0             0              1             0          0       White      Hispanic
2      DEPP  JOHNNY    NaN             0          0             0              0             0          1     Unknown         White
3     DICAP     LEO    NaN             0          0             0              0             0          1     Unknown         White
4    BRANDO  MARLON      E             0          0             0              0             0          0       White         Other
5     HANKS     TOM    NaN             0          0             0              0             0          1     Unknown         White
6    DENIRO  ROBERT      E             0          1             0              0             0          1       White   Two Or More
7    PACINO      AL      E             0          0             0              0             0          1       White         White
8  WILLIAMS   ROBIN      E             0          0             1              0             0          0       White  Haw/Pac Isl.
9  EASTWOOD   CLINT      E             0          0             0              0             0          1       White         White

69
কেবলমাত্র একটি নোট: আপনি যদি কেবল নিজের ফাংশনে সারিটি খাওয়ান তবে আপনি কেবল এটি করতে পারেন:df.apply(label_race, axis=1)
পল এইচ

1
যদি আমি অন্য সারির সাথে অনুরূপ কিছু করতে চাই তবে আমি কি একই ফাংশনটি ব্যবহার করতে পারি? উদাহরণস্বরূপ, ফলাফলগুলি থেকে, যদি ['রেস_লাবেল'] == "হোয়াইট" ফিরে আসে 'হোয়াইট' ইত্যাদি। তবে যদি ['রেস_এলবেল'] == 'অজানা' মানগুলি ['rno_defined'] কলাম থেকে ফেরত দেয়। আমি ধরে নিই একই ফাংশনটি কাজ করবে তবে অন্য কলাম থেকে মানগুলি কীভাবে পাবেন তা অনুভব করতে পারছি না।
ডেভ

2
আপনি একটি নতুন ফাংশন লিখতে পারেন, যা 'রেস_লেবেল' ফিল্ডটি দেখে এবং ফলাফলগুলি একটি নতুন ক্ষেত্রে প্রেরণ করতে পারে, বা - এবং আমি মনে করি এটির ক্ষেত্রে এটি আরও ভাল হতে পারে, মূল ফাংশনটি সম্পাদনা করে, চূড়ান্ত return 'Other'লাইনটি পরিবর্তন করতে হবে return row['rno_defined']যা সেই ক্ষেত্রে কলাম থেকে মানটি প্রতিস্থাপন করুন যেখানে / তারপর বিবৃতিগুলির সেটটি কোনও মিল খুঁজে পায় না (যেমন বর্তমানে আপনি 'অন্যান্য' দেখতে পাচ্ছেন)।
থমাস কিম্বার

9
আপনি প্রক্রিয়া সহজ করতে পারেন: df.apply(lambda row: label_race (row),axis=1)থেকেdf.apply(label_race, axis=1)
user48956

5
আরও নতুন সংস্করণগুলিতে, আপনি যদি 'সেটিংবিথকপি ওয়ার্নিং' পান তবে আপনার 'এসাইন' পদ্ধতিটি দেখে নেওয়া উচিত। দেখুন: stackoverflow.com/a/12555510/3015186
np8

218

যেহেতু 'অন্যের কাছ থেকে প্যান্ডাস নতুন কলামের' জন্য এটি গুগলের প্রথম ফলাফল, তাই এখানে একটি সরল উদাহরণ রয়েছে:

import pandas as pd

# make a simple dataframe
df = pd.DataFrame({'a':[1,2], 'b':[3,4]})
df
#    a  b
# 0  1  3
# 1  2  4

# create an unattached column with an index
df.apply(lambda row: row.a + row.b, axis=1)
# 0    4
# 1    6

# do same but attach it to the dataframe
df['c'] = df.apply(lambda row: row.a + row.b, axis=1)
df
#    a  b  c
# 0  1  3  4
# 1  2  4  6

আপনি যদি এটি পান তবে SettingWithCopyWarningআপনি এটিও এভাবে করতে পারেন:

fn = lambda row: row.a + row.b # define a function for the new column
col = df.apply(fn, axis=1) # get column data with an index
df = df.assign(c=col.values) # assign values to column 'c'

সূত্র: https://stackoverflow.com/a/12555510/243392

এবং যদি আপনার কলামের নামটিতে ফাঁকা জায়গা থাকে আপনি এই জাতীয় বাক্য ব্যবহার করতে পারেন:

df = df.assign(**{'some column name': col.values})

এবং এখানে জন্য ডকুমেন্টেশন আবেদন , এবং বরাদ্দ


1
সংক্ষিপ্ত উত্তর, নিঃসরণে প্রয়োজনীয়!
ফ্রয়েড আকসেলসন

1
আমি SettingWithCopyWarningযখন যা করছি আমি তা পাচ্ছি df['c'] = df.apply(lambda row: row.a + row.b, axis=1) কি এটি কি এখানেই আসল সমস্যা, বা আমার এ নিয়ে চিন্তা করা উচিত নয়?
নাট

2
@ নাট আমি কখনই সেই সতর্কতা পাইনি - সম্ভবত এটি ডেটাফ্রেমের ডেটার উপর নির্ভর করে? তবে আমি 2017 থেকে অন্য উত্তরের ভিত্তিতে উত্তরটির প্রশংসা করেছি
ব্রায়ান বার্নস

56

উপরের উত্তরগুলি পুরোপুরি বৈধ, তবে আকারে একটি ভেক্টরাইজড সমাধান বিদ্যমান numpy.select। এটি আপনাকে শর্তগুলি সংজ্ঞায়িত করতে, তারপরে শর্তগুলির জন্য আউটপুটগুলি সংজ্ঞায়িত করতে সহায়তা করে যা ব্যবহারের চেয়ে অনেক বেশি দক্ষতার সাথে apply:


প্রথমে শর্তসমূহ সংজ্ঞায়িত করুন:

conditions = [
    df['eri_hispanic'] == 1,
    df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1),
    df['eri_nat_amer'] == 1,
    df['eri_asian'] == 1,
    df['eri_afr_amer'] == 1,
    df['eri_hawaiian'] == 1,
    df['eri_white'] == 1,
]

এখন, সম্পর্কিত আউটপুটগুলি সংজ্ঞায়িত করুন:

outputs = [
    'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White'
]

শেষ অবধি numpy.select:

res = np.select(conditions, outputs, 'Other')
pd.Series(res)

0           White
1        Hispanic
2           White
3           White
4           Other
5           White
6     Two Or More
7           White
8    Haw/Pac Isl.
9           White
dtype: object

কেন numpy.selectব্যবহার করা উচিত apply? এখানে কিছু পারফরম্যান্স চেক রয়েছে:

df = pd.concat([df]*1000)

In [42]: %timeit df.apply(lambda row: label_race(row), axis=1)
1.07 s ± 4.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [44]: %%timeit
    ...: conditions = [
    ...:     df['eri_hispanic'] == 1,
    ...:     df[['eri_afr_amer', 'eri_asian', 'eri_hawaiian', 'eri_nat_amer', 'eri_white']].sum(1).gt(1),
    ...:     df['eri_nat_amer'] == 1,
    ...:     df['eri_asian'] == 1,
    ...:     df['eri_afr_amer'] == 1,
    ...:     df['eri_hawaiian'] == 1,
    ...:     df['eri_white'] == 1,
    ...: ]
    ...:
    ...: outputs = [
    ...:     'Hispanic', 'Two Or More', 'A/I AK Native', 'Asian', 'Black/AA', 'Haw/Pac Isl.', 'White'
    ...: ]
    ...:
    ...: np.select(conditions, outputs, 'Other')
    ...:
    ...:
3.09 ms ± 17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

ব্যবহার numpy.selectআমাদের ব্যাপক উন্নত কর্মক্ষমতা দেয় এবং তাত্পর্য কেবলমাত্র ডেটা বাড়ার সাথে সাথে বাড়বে।


7
এই সমাধান তাই আন্ডাররেটেড হয়। আমি জানতাম যে আমি প্রয়োগের সাথে অনুরূপ কিছু করতে পারি তবে হাজার হাজার ফাইলের জন্য আমাকে এই অপারেশনটি করতে হওয়ায় বিকল্পের সন্ধান করছি। আমি আপনার পোস্ট খুঁজে পেয়েছি তাই খুশি।
এমএলএক্স

অনুরূপ কিছু তৈরি করতে আমার সমস্যা হচ্ছে। আমি "সিরিজের সত্য মানটি অস্পষ্ট ..." ত্রুটি বার্তাটি পেয়েছি। আমার কোডটি কানসাস_সিটি = ['এনডি', 'এসডি', 'এনই', 'কেএস', 'এমএন', 'আইএ', 'এমও'] শর্তাবলী = [ডিএফ_ডর্ম ['রাজ্য_লফা'] ক্যানসাস_সিটি] আউটপুটগুলিতে = [' কানসাস সিটি '] ডিএফ_মার্জ [' অঞ্চল '] = এনপি.ইলেক্ট করুন (শর্ত, আউটপুট,' অন্যান্য ') কোনও সহায়তা করতে পারে?
শন শ্রায়ার

2
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। অন্যগুলি ঠিক আছে তবে একবার আপনি বড় ডেটাতে কাজ করার পরে, এটিই কেবলমাত্র কাজ করে, এবং এটি আশ্চর্যজনকভাবে দ্রুত কাজ করে।
দ্য প্রলেটারিয়েট

29

.apply()প্রথম প্যারামিটার হিসাবে একটি ফাংশন লাগে; label_raceফাংশনে যেমন পাস :

df['race_label'] = df.apply(label_race, axis=1)

কোনও ফাংশনে পাস করার জন্য আপনার একটি ল্যাম্বডা ফাংশন তৈরি করার দরকার নেই।


12

এটা চেষ্টা কর,

df.loc[df['eri_white']==1,'race_label'] = 'White'
df.loc[df['eri_hawaiian']==1,'race_label'] = 'Haw/Pac Isl.'
df.loc[df['eri_afr_amer']==1,'race_label'] = 'Black/AA'
df.loc[df['eri_asian']==1,'race_label'] = 'Asian'
df.loc[df['eri_nat_amer']==1,'race_label'] = 'A/I AK Native'
df.loc[(df['eri_afr_amer'] + df['eri_asian'] + df['eri_hawaiian'] + df['eri_nat_amer'] + df['eri_white']) > 1,'race_label'] = 'Two Or More'
df.loc[df['eri_hispanic']==1,'race_label'] = 'Hispanic'
df['race_label'].fillna('Other', inplace=True)

O / পি:

     lname   fname rno_cd  eri_afr_amer  eri_asian  eri_hawaiian  \
0      MOST    JEFF      E             0          0             0   
1    CRUISE     TOM      E             0          0             0   
2      DEPP  JOHNNY    NaN             0          0             0   
3     DICAP     LEO    NaN             0          0             0   
4    BRANDO  MARLON      E             0          0             0   
5     HANKS     TOM    NaN             0          0             0   
6    DENIRO  ROBERT      E             0          1             0   
7    PACINO      AL      E             0          0             0   
8  WILLIAMS   ROBIN      E             0          0             1   
9  EASTWOOD   CLINT      E             0          0             0   

   eri_hispanic  eri_nat_amer  eri_white rno_defined    race_label  
0             0             0          1       White         White  
1             1             0          0       White      Hispanic  
2             0             0          1     Unknown         White  
3             0             0          1     Unknown         White  
4             0             0          0       White         Other  
5             0             0          1     Unknown         White  
6             0             0          1       White   Two Or More  
7             0             0          1       White         White  
8             0             0          0       White  Haw/Pac Isl.  
9             0             0          1       White         White 

.locপরিবর্তে ব্যবহার করুন apply

এটি ভেক্টরাইজেশনের উন্নতি করে।

.loc সহজ পদ্ধতিতে কাজ করে, শর্তের উপর ভিত্তি করে সারিগুলিকে মাস্ক করে, হিমায়িত সারিগুলিতে মান প্রয়োগ করে।

আরও বিশদে বিশদটি দেখুন, .loc ডক্স

কর্মক্ষমতা বৈশিষ্ট্যের মান:

গৃহীত উত্তর:

def label_race (row):
   if row['eri_hispanic'] == 1 :
      return 'Hispanic'
   if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 :
      return 'Two Or More'
   if row['eri_nat_amer'] == 1 :
      return 'A/I AK Native'
   if row['eri_asian'] == 1:
      return 'Asian'
   if row['eri_afr_amer']  == 1:
      return 'Black/AA'
   if row['eri_hawaiian'] == 1:
      return 'Haw/Pac Isl.'
   if row['eri_white'] == 1:
      return 'White'
   return 'Other'

df=pd.read_csv('dataser.csv')
df = pd.concat([df]*1000)

%timeit df.apply(lambda row: label_race(row), axis=1)

প্রতি লুপটিতে 1.15 s ± 46.5 এমএস (7 of রানের গড় ± স্ট্যান্ড। ডিভ। প্রতিটি লুপ প্রতিটি)

আমার প্রস্তাবিত উত্তর:

def label_race(df):
    df.loc[df['eri_white']==1,'race_label'] = 'White'
    df.loc[df['eri_hawaiian']==1,'race_label'] = 'Haw/Pac Isl.'
    df.loc[df['eri_afr_amer']==1,'race_label'] = 'Black/AA'
    df.loc[df['eri_asian']==1,'race_label'] = 'Asian'
    df.loc[df['eri_nat_amer']==1,'race_label'] = 'A/I AK Native'
    df.loc[(df['eri_afr_amer'] + df['eri_asian'] + df['eri_hawaiian'] + df['eri_nat_amer'] + df['eri_white']) > 1,'race_label'] = 'Two Or More'
    df.loc[df['eri_hispanic']==1,'race_label'] = 'Hispanic'
    df['race_label'].fillna('Other', inplace=True)
df=pd.read_csv('s22.csv')
df = pd.concat([df]*1000)

%timeit label_race(df)

প্রতি লুপে 24.7 এমএস ± 1.7 এমএস (7 runs রানের গড় ± স্ট্যান্ডার্ড। প্রতি 10 টি লুপ)

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