আমার পান্ডারা কেন 'প্রয়োগ' ফাংশনটি একাধিক কলামগুলিতে কাজ করছে না? [বন্ধ]


239

নীচের ডাটাফ্রেমের সাথে একাধিক কলাম ব্যবহার করার সময়, পান্ডা প্রয়োগের সাথে আমার কিছু সমস্যা রয়েছে

df = DataFrame ({'a' : np.random.randn(6),
                 'b' : ['foo', 'bar'] * 3,
                 'c' : np.random.randn(6)})

এবং নিম্নলিখিত ফাংশন

def my_test(a, b):
    return a % b

যখন আমি এই ফাংশনটি প্রয়োগ করার চেষ্টা করি:

df['Value'] = df.apply(lambda row: my_test(row[a], row[c]), axis=1)

আমি ত্রুটি বার্তা পেয়েছি:

NameError: ("global name 'a' is not defined", u'occurred at index 0')

আমি এই বার্তাটি বুঝতে পারি না, আমি নামটি সঠিকভাবে সংজ্ঞা দিয়েছি।

আমি এই ইস্যুতে যে কোনও সহায়তার খুব প্রশংসা করব

হালনাগাদ

আপনার সাহায্যের জন্য ধন্যবাদ. কোডটি দিয়ে আমি প্রকৃতপক্ষে কিছু বাক্য গঠন ভুল করেছি, সূচিটি রাখা উচিত '। তবে আমি এখনও আরও জটিল ফাংশন ব্যবহার করে একই সমস্যাটি পেয়েছি যেমন:

def my_test(a):
    cum_diff = 0
    for ix in df.index():
        cum_diff = cum_diff + (a - df['a'][ix])
    return cum_diff 

1
applyযতটা সম্ভব ব্যবহার করা থেকে বিরত থাকুন। আপনার যদি এটির নিশ্চিত হওয়া না হয় তবে আপনি সম্ভবত এটি ব্যবহার করবেন না। আমি কখন একবার আমার কোডে পান্ডা প্রয়োগ () ব্যবহার করতে চাই তা একবার দেখার পরামর্শ দিই?
cs95

এটি কেবল একটি ডেটাফ্রেম কলামের উল্লেখ করে সিনট্যাক্স ত্রুটি সম্পর্কে এবং ফাংশনগুলিতে যুক্তিগুলির প্রয়োজন কেন why আপনার দ্বিতীয় প্রশ্ন হিসাবে, ফাংশনটি my_test(a)জানে না dfযেহেতু এটি আর্গুমেন্ট হিসাবে পাস করা হয়নি (যদি না dfবিশ্বব্যাপী বলে মনে করা হয় যা ভয়ানক অনুশীলন হবে)। আর্গুমেন্ট হিসাবে একটি ফাংশনের ভিতরে আপনার প্রয়োজনীয় সমস্ত মানগুলি পাস করতে হবে (অগ্রাধিকার ক্রমে), অন্যথায় ফাংশনটি dfকোথা থেকে আসে তা অন্য কীভাবে জানতে পারে ? এছাড়াও, গ্লোবাল ভেরিয়েবলের সাথে জড়িত একটি নেমস্পেসে প্রোগ্রাম করা খারাপ অভ্যাস, আপনি এর মতো ত্রুটিগুলি ধরবেন না।
স্মি

উত্তর:


379

মনে হচ্ছে আপনি ''নিজের স্ট্রিংটির কথা ভুলে গেছেন ।

In [43]: df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)

In [44]: df
Out[44]:
                    a    b         c     Value
          0 -1.674308  foo  0.343801  0.044698
          1 -2.163236  bar -2.046438 -0.116798
          2 -0.199115  foo -0.458050 -0.199115
          3  0.918646  bar -0.007185 -0.001006
          4  1.336830  foo  0.534292  0.268245
          5  0.976844  bar -0.773630 -0.570417

বিটিডাব্লু, আমার মতে, নিম্নলিখিত উপায়টি আরও মার্জিত:

In [53]: def my_test2(row):
....:     return row['a'] % row['c']
....:     

In [54]: df['Value'] = df.apply(my_test2, axis=1)

ধন্যবাদ, আপনি ঠিক বলেছেন আমি '' ভুলে গেছি। তবে আরও জটিল ফাংশন নিয়ে আমার এখনও একই সমস্যা রয়েছে। আমি এটির সাথে আপনার সহায়তার অত্যন্ত প্রশংসা করব। ধন্যবাদ
অ্যান্ডি

5
@ অ্যানডি অনুসরণ করে [53-54] আপনাকে আরও জটিল ফাংশন প্রয়োগ করার অনুমতি দেয়।
অ্যান্ডি হেডেন

@ এবং আপনি আপনার [53] উপায়ের মতো জটিল ক্রিয়াটি সংজ্ঞায়িত করতে পারেন।
ওয়েটিংকুও

সমস্ত প্রয়োগ কৌশল একই সঞ্চালন না? আমি পান্ডাতে নতুন এবং সর্বদা সামান্য রহস্যজনক প্রয়োগ খুঁজে পেয়েছি তবে আপনার কৌশলটি [৫৩-৫৪] আমার পক্ষে বুঝতে সহজ (এবং আশা করি মনে রাখতে হবে) ... বড় টেবিলে এটি অন্য রূপের প্রয়োগের মতোই দ্রুত উপস্থাপন?
কেন

কেন এটি পৃথক পদ্ধতি তৈরি করা আরও মার্জিত হিসাবে বিবেচিত হয় - এমনকি ক্ষুদ্রতর পদ্ধতির জন্যও। আমি 7 বছর ধরে অজগরটিতে উল্লেখযোগ্য প্রকল্পগুলি করছি তবে সম্ভবত pythonistaএটিকে সহ কিছু দৃষ্টিভঙ্গির কারণে কখনও বিবেচনা করা হবে না ।
জাভাদবা

33

আপনি যদি কেবল (কলাম ক)% (কলাম বি) গণনা করতে চান তবে আপনার প্রয়োজন হবে না apply, কেবল এটি সরাসরি করুন:

In [7]: df['a'] % df['c']                                                                                                                                                        
Out[7]: 
0   -1.132022                                                                                                                                                                    
1   -0.939493                                                                                                                                                                    
2    0.201931                                                                                                                                                                    
3    0.511374                                                                                                                                                                    
4   -0.694647                                                                                                                                                                    
5   -0.023486                                                                                                                                                                    
Name: a

16
আমি জানি, একাধিক কলামে একটি ফাংশন প্রয়োগে আমার সমস্যাটি দেখাতে এটি কেবল উদাহরণ
অ্যান্ডি

18

ধরা যাক আমরা ডেটাফ্রেম ডিএফের কলাম 'এ' এবং 'বি' কলামগুলিতে একটি ফাংশন অ্যাড 5 প্রয়োগ করতে চাই

def add5(x):
    return x+5

df[['a', 'b']].apply(add5)

আপনার কোড স্নিপেট চেষ্টা করার সময় আমি নিম্নলিখিত ত্রুটি পেয়ে যাচ্ছি। প্রকারের ত্রুটি: ('অবশ্যই স্ট্রাক্ট হতে হবে, অন্তর্নিহিত হবে না', 'সূচী বি তে ঘটেছে') আপনি কি দয়া করে তা দেখতে পারেন।
debaonline4u 8:58

আপনার ডেটাফ্রেমের কলাম বি একটি স্ট্রিং টাইপ বা অবজেক্ট টাইপ কলাম, এটি একটি সংখ্যার সাথে যোগ করার জন্য একটি পূর্ণসংখ্যা কলাম হওয়া উচিত।
মির_মুর্তজা 8'18

পরিবর্তনগুলি কেবল নিয়োগের পরে প্রয়োগ হবে না?
এস এএড

11

উপরের সমস্ত পরামর্শ কাজ করে, তবে আপনি যদি আরও বেশি দক্ষতার সাথে আপনার কম্পিউটেশনগুলি চান তবে আপনার নম্পু ভেক্টর ক্রিয়াকলাপটি গ্রহণ করা উচিত (এখানে উল্লিখিত হিসাবে)

import pandas as pd
import numpy as np


df = pd.DataFrame ({'a' : np.random.randn(6),
             'b' : ['foo', 'bar'] * 3,
             'c' : np.random.randn(6)})

উদাহরণ 1: এর সাথে লুপিং pandas.apply():

%%timeit
def my_test2(row):
    return row['a'] % row['c']

df['Value'] = df.apply(my_test2, axis=1)

সবচেয়ে ধীরতম রানটি দ্রুততমের চেয়ে 7.49 গুণ বেশি সময় নিয়েছে। এর অর্থ এই হতে পারে যে একটি মধ্যবর্তী ফলাফল ক্যাশে হচ্ছে। 1000 লুপগুলি, প্রতি লুপে 3: 481 µ এস সেরা

উদাহরণ 2: ভেক্টরাইজ ব্যবহার করে pandas.apply():

%%timeit
df['a'] % df['c']

সবচেয়ে ধীরতম রানটি দ্রুততমের চেয়ে 458.85 গুণ বেশি সময় নিয়েছে। এর অর্থ এই হতে পারে যে একটি মধ্যবর্তী ফলাফল ক্যাশে হচ্ছে। 10000 লুপ, প্রতি লুপে 3: 70.9 µ এর মধ্যে সেরা

উদাহরণ 3: ন্যালি অ্যারে ব্যবহার করে ভেক্টরাইজ করুন:

%%timeit
df['a'].values % df['c'].values

সবচেয়ে ধীরতম রানটি দ্রুততমের চেয়ে 9.৯৮ গুণ বেশি সময় নিয়েছে। এর অর্থ এই হতে পারে যে একটি মধ্যবর্তী ফলাফল ক্যাশে হচ্ছে। 100000 লুপ, প্রতি লুপে 3: 6.39 µ এর মধ্যে সেরা

সুতরাং নম্পি অ্যারে ব্যবহার করে ভেক্টরাইজিং প্রায় দুই অর্ধ মাত্রার গতি উন্নত করেছে।


বড় সংখ্যার জন্য ফলাফল আরও নাটকীয়ভাবে পরিবর্তিত হয়, যেমন 10 কে দিয়ে 6 প্রতিস্থাপন, আমি যথাক্রমে 248 এমএস, 332 এস, 263 µ গুলি পাই। সুতরাং উভয় ভেক্টরাইজড সমাধান একে অপরের খুব কাছাকাছি, তবে নন-ভেক্টরাইজড দ্রবণটি 1000 গুণ ধীর। (পাইথন
-৩.৩ এ

3

এটি পূর্ববর্তী সমাধান হিসাবে একই তবে আমি df.apply নিজেই ফাংশনটি সংজ্ঞায়িত করেছি:

df['Value'] = df.apply(lambda row: row['a']%row['c'], axis=1)

2

উপরে বর্ণিত তিনটির তুলনা আমি দিয়েছি।

মান ব্যবহার করা হচ্ছে

% টাইমিট ডিএফ ['মান'] = ডিএফ ['এ']। মান% ডিএফ ['সি']। মান

লুপ প্রতি 139 µs ± 1.91 µs (7 ± রানের গড় ± স্ট্যান্ড। দেব, প্রতিটি 10000 লুপ)

মান ছাড়া

% টাইমিট ডিএফ ['মান'] = ডিএফ ['এ']% ডিএফ ['সি'] 

লুপ প্রতি 216 ±s ± 1.86 µs (অর্থাত্ runs স্ট্যান্ড। Runs রানের ডেভেলড, প্রতিটি 1000 লুপ)

ফাংশন প্রয়োগ করুন

% টাইমিট ডিএফ ['মান'] = ডিএফ.প্লাই (ল্যাম্বডা সারি: সারি ['a']% সারি ['সি'], অক্ষ = 1)

প্রতি লুপ 474 µs ± 5.07 µs (অর্থাত্ runs স্ট্যান্ড। Runs রানের ডেভেলড, প্রতিটি 1000 লুপ)

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