সারি সারি সারি পুনরাবৃত্তি করার সময় পান্ডাসে ডেটাফ্রেম আপডেট করুন


213

আমার কাছে একটি পান্ডাস ডেটা ফ্রেম রয়েছে যা দেখতে এটি দেখতে (এটি বেশ বড় একটি)

           date      exer exp     ifor         mat  
1092  2014-03-17  American   M  528.205  2014-04-19 
1093  2014-03-17  American   M  528.205  2014-04-19 
1094  2014-03-17  American   M  528.205  2014-04-19 
1095  2014-03-17  American   M  528.205  2014-04-19    
1096  2014-03-17  American   M  528.205  2014-05-17 

এখন আমি সারিতে সারিটি পুনরাবৃত্তি করতে চাই এবং প্রতিটি সারির মধ্য দিয়ে যাওয়ার সাথে সাথে প্রতিটি সারির মান ifor কিছু শর্তের উপর নির্ভর করে পরিবর্তিত হতে পারে এবং আমাকে অন্য ডেটা ফ্রেমের সন্ধান করতে হবে।

আমি পুনরাবৃত্তি করার সাথে সাথে এটি কীভাবে আপডেট করব। কয়েকটি জিনিস চেষ্টা করে দেখেছি তারা কেউই কাজ করে নি।

for i, row in df.iterrows():
    if <something>:
        row['ifor'] = x
    else:
        row['ifor'] = y

    df.ix[i]['ifor'] = x

এই পদ্ধতির কোনওটিই কাজ করে বলে মনে হচ্ছে না। আমি ডেটা ফ্রেমে আপডেট হওয়া মানগুলি দেখতে পাচ্ছি না।


2
আমি মনে করি আপনি চান df.ix[i,'ifor']df.ix[i]['ifor']সমস্যাযুক্ত কারণ এটি শৃঙ্খলিত শৃঙ্খলাবদ্ধ (যা পান্ডায় নির্ভরযোগ্য নয়)।
কার্ল ডি

1
আপনি যেমন অন্য ফ্রেম সরবরাহ করতে পারেন <something>। আপনার কোডটি ভেক্টরাইজ করা যায় কিনা সেগুলি নির্ভর করে things সাধারণভাবে, এড়ানো iterrows। আপনার ক্ষেত্রে, আপনার অবশ্যই এটি এড়ানো উচিত কারণ প্রতিটি সারিটি objectটাইপযুক্ত হবে Series
ফিলিপ ক্লাউড

আপনি আপনার অবস্থার জন্য বুলিয়ান মাস্ক তৈরি করা ভাল those সমস্ত সারি আপডেট করুন এবং তারপরে
বাকীটিকে

দয়া করে এটিরোজ () ব্যবহার করবেন না। এটি পান্ডার ইতিহাসের সবচেয়ে খারাপ এন্টি-প্যাটার্নের একটি স্পষ্ট সক্ষম enable
সিএস 95

উত্তর:


232

আপনি df.set_value ব্যবহার করে লুপে মান নির্ধারণ করতে পারেন:

for i, row in df.iterrows():
    ifor_val = something
    if <condition>:
        ifor_val = something_else
    df.set_value(i,'ifor',ifor_val)

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

হালনাগাদ

df.set_value () সংস্করণ 0.21.0 থেকে অবহেলা করা হয়েছে আপনি তার পরিবর্তে df.at () ব্যবহার করতে পারেন:

for i, row in df.iterrows():
    ifor_val = something
    if <condition>:
        ifor_val = something_else
    df.at[i,'ifor'] = ifor_val

6
দেখুন pandas.pydata.org/pandas-docs/stable/generated/... , দ্বিতীয় বুলেট: "2.You কিছু মাধ্যমে iterating সংশোধন না করা উচিত"
Davor Josipovic

32
আমি নিশ্চিত না যে আমরা এটি ঠিক একইভাবে পড়ি কিনা। আপনি যদি আমার সিউডো কোডটি দেখেন তবে আমি ডেটাফ্রেমে সংশোধন করি, পুনরাবৃত্তির মান থেকে নয়। পুনরুক্তি মানটি কেবল মান / অবজেক্টের সূচকের জন্য ব্যবহৃত হয়। যা ব্যর্থ হবে তা হ'ল সারি ['ifor'] = ডকুমেন্টেশনে উল্লিখিত কারণে।
রাক্কে

3
সুস্পষ্ট করার জন্য ধন্যবাদ.
জোসিপোভিচ

8
এখন সেট_ভ্যালুটিও ত্রুটিযুক্ত, এবং .at (বা .আইটি) ব্যবহার করা উচিত, সুতরাং আমার লুপটি দেখতে দেখতে: i, সারি ডিএফ.ইরোজে (): ifor_val = কিছু যদি <শর্ত>: ifor_val = কিছু_else df.at [ i, 'ifor'] = ifor_val
জটিল এম

2
সেট_ভ্যালু হ্রাস করা হয় এবং ভবিষ্যতে প্রকাশে মুছে ফেলা হবে। পরিবর্তে .at [] বা .at [] অ্যাক্সেসরগুলি ব্যবহার করুন
রায়উমেআইএক্স

75

পান্ডস ডেটাফ্রেম অবজেক্টটি সিরিজের একটি সিরিজ হিসাবে ভাবা উচিত। অন্য কথায়, আপনার এটি কলামগুলির ক্ষেত্রে বিবেচনা করা উচিত। কেন এটি গুরুত্বপূর্ণ তা কারণ হ'ল আপনি যখন ব্যবহার করবেন তখন pd.DataFrame.iterrowsসারি দিয়ে সিরিজ হিসাবে পুনরাবৃত্তি হচ্ছেন । কিন্তু এই না সিরিজ যে ডেটা ফ্রেম সংরক্ষণ করছে না এবং তাই তারা নতুন সিরিজ তোমার জন্য তৈরি করা হয় যে আপনি পুনরুক্তি হয়। এর দ্বারা বোঝা যায় যে আপনি যখন তাদের এ্যুকেন্ড করার চেষ্টা করবেন তখন সেই সম্পাদনাগুলি মূল ডেটা ফ্রেমে প্রতিফলিত হবে না।

ঠিক আছে, এখন যে উপায়টির বাইরে: আমরা কী করব?

এই পোস্টের আগে পরামর্শগুলি অন্তর্ভুক্ত:

  1. pd.DataFrame.set_valueপান্ডাস সংস্করণ 0.21 হিসাবে অবহেলা করা হয়েছে
  2. pd.DataFrame.ixহয় অবচিত
  3. pd.DataFrame.locঠিক আছে তবে অ্যারে সূচকগুলিতে কাজ করতে পারেন এবং আপনি আরও ভাল করতে পারেন

আমার সুপারিশ
ব্যবহার করুনpd.DataFrame.at

for i in df.index:
    if <something>:
        df.at[i, 'ifor'] = x
    else:
        df.at[i, 'ifor'] = y

আপনি এটি এটিকে পরিবর্তন করতে পারেন:

for i in df.index:
    df.at[i, 'ifor'] = x if <something> else y

প্রতিক্রিয়া মন্তব্য

এবং যদি আমার যদি শর্তের জন্য পূর্ববর্তী সারির মানটি ব্যবহার করা দরকার?

for i in range(1, len(df) + 1):
    j = df.columns.get_loc('ifor')
    if <something>:
        df.iat[i - 1, j] = x
    else:
        df.iat[i - 1, j] = y

এবং যদি আমার যদি শর্তের জন্য পূর্ববর্তী সারির মানটি ব্যবহার করা দরকার? ওজি ডিএফ-তে একটি স্তব্ধ কলাম যুক্ত করবেন?
ইউকা

দক্ষতা অনুসারে, আপনার পদ্ধতির তুলনায় কোনও ল্যাগড কলাম যুক্ত করা ভাল বা প্রভাবটি ছোট ডেটাসেটের জন্য নগণ্য? (<10 কে সারি)
ইউকা

সেটা নির্ভর করে. আমি একটি পিছনে কলাম ব্যবহার করতে যাব। এই উত্তরটি দেখিয়ে দিচ্ছে যে আপনার অবশ্যই লুপ করবেন। তবে যদি আপনাকে লুপ করতে না হয় তবে তা করবেন না।
পাইরাস্কোয়ার

এটি পেয়েছেন, এছাড়াও যদি আপনার স্ট্যাকওভারফ্লো.com/q/51753001/9754169 এর জন্য আপনার মতামত পাওয়া সম্ভব হয় তবে এটি দুর্দান্ত হবে: ডি
ইউকা

পুরানো বিকল্পগুলির সাথে .at [] বিচ্ছিন্ন করার জন্য দুর্দান্ত
জাস্টাস

35

আপনি যে পদ্ধতিটি ব্যবহার করতে পারেন তা হ'ল itertuples()এটি ডেটফ্রেম সারিগুলিকে নেমেডটপলস হিসাবে পুনরাবৃত্তি করে, এতে টিউপলের প্রথম উপাদান হিসাবে সূচকের মান থাকে। এবং এটি তুলনায় অনেক দ্রুত iterrows()। এর জন্য itertuples(), প্রতিটি এর ডেটাফ্রেমে rowরয়েছে Indexএবং আপনি locমান সেট করতে ব্যবহার করতে পারেন ।

for row in df.itertuples():
    if <something>:
        df.at[row.Index, 'ifor'] = x
    else:
        df.at[row.Index, 'ifor'] = x

    df.loc[row.Index, 'ifor'] = x

বেশিরভাগ ক্ষেত্রেই অধীনে, itertuples()দ্রুত চেয়ে iatবা at

ধন্যবাদ @ সান্টিস্টসপুরি, এর চেয়ে অনেক দ্রুতগতি ব্যবহার .atকরাloc


3
যেহেতু আপনি কেবল একটি সূক্ষ্ম সূচকেই নির্দেশ করেছেন তাই আপনি আপনার কর্মক্ষমতা উন্নত করতে .loc এর পরিবর্তে .at ব্যবহারের কথা ভাবতে পারেন। এই সম্পর্কে আরও তথ্যের জন্য এই প্রশ্নটি দেখুন
সানটিস্টসপুয়ারি

অদ্ভুত চিন্তা কিন্তু df.loc[row.Index, 3] = xকাজ করে না। অন্যদিকে, df.loc[row.Index, 'ifor'] = xকাজ!
seralouk

19

আপনার পরিবর্তে df.ix[i, 'exp']=Xবা এর df.loc[i, 'exp']=Xপরিবর্তে মান নির্ধারণ করা উচিত df.ix[i]['ifor'] = x

অন্যথায় আপনি একটি দৃশ্যে কাজ করছেন এবং একটি উষ্ণতা পাওয়া উচিত:

-c:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead

তবে অবশ্যই, DataFrame@ ফিলিপ ক্লাউডের পরামর্শ অনুসারে লুপটি সম্ভবত কিছু ভেক্টরাইজড অ্যালগরিদম দ্বারা আরও ভালভাবে প্রতিস্থাপন করা উচিত ।


10

ঠিক আছে, আপনি যদি কোনওভাবে পুনরাবৃত্তি করতে চলেছেন তবে কেন সকলের সহজ পদ্ধতিটি ব্যবহার করবেন না, df['Column'].values[i]

df['Column'] = ''

for i in range(len(df)):
    df['Column'].values[i] = something/update/new_value

অথবা আপনি যদি নতুন মানগুলি পুরানো বা এর মতো যে কোনও কিছুর সাথে তুলনা করতে চান তবে কেন এটি একটি তালিকায় সংরক্ষণ করবেন না এবং শেষ পর্যন্ত যুক্ত করুন।

mylist, df['Column'] = [], ''

for <condition>:
    mylist.append(something/update/new_value)

df['Column'] = mylist


0

এটি ব্যবহার করে lambdaফাংশনগুলি ব্যবহার করা আরও ভাল df.apply()-

df["ifor"] = df.apply(lambda x: {value} if {condition} else x["ifor"], axis=1)

-3

একটি কলাম থেকে MAX সংখ্যা বৃদ্ধি করুন। উদাহরণ স্বরূপ :

df1 = [sort_ID, Column1,Column2]
print(df1)

আমার আউটপুট:

Sort_ID Column1 Column2
12         a    e
45         b    f
65         c    g
78         d    h

MAX = df1['Sort_ID'].max() #This returns my Max Number 

এখন, আমাকে df2 এ একটি কলাম তৈরি করতে হবে এবং কলাম মানগুলি পূরণ করতে হবে যা MAX বৃদ্ধি করে incre

Sort_ID Column1 Column2
79      a1       e1
80      b1       f1
81      c1       g1
82      d1       h1

দ্রষ্টব্য: df2 প্রাথমিকভাবে কেবল কলাম 1 এবং কলাম 2 অন্তর্ভুক্ত করবে। df1 থেকে MAX এর বর্ধিত ও বর্ধিত করার জন্য আমাদের Sortid কলাম দরকার।

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