পান্ডাস ডেটা ফ্রেমের কলামগুলি সাধারণ করুন


226

পান্ডাসে আমার একটি ডেটাফ্রেম রয়েছে যেখানে প্রতিটি কলামে আলাদা মান সীমা থাকে। উদাহরণ স্বরূপ:

ডিএফ:

A     B   C
1000  10  0.5
765   5   0.35
800   7   0.09

প্রতিটি মান 0 এবং 1 এর মধ্যে যেখানে আমি এই ডেটাফ্রেমের কলামগুলি কীভাবে সাধারণ করতে পারি তার কোনও ধারণা?

আমার কাঙ্ক্ষিত ফলাফল:

A     B    C
1     1    1
0.765 0.5  0.7
0.8   0.7  0.18(which is 0.09/0.5)

1
একটি প্রয়োগ ফাংশন রয়েছে, যেমন ফ্রেম.প্লাই (চ, অক্ষ = 1) যেখানে f এমন একটি ফাংশন যা একটি সারিতে কিছু করে ...
tschm

1
সাধারণকরণ সবচেয়ে উপযুক্ত শব্দভাজন হতে পারে না, যেহেতু বিজ্ঞান-বিজ্ঞান ডকুমেন্টেশন এটিকে " ইউনিট আদর্শের জন্য পৃথক নমুনাগুলির স্কেল করার প্রক্রিয়া " (অর্থাত্ যদি আমি এটি সঠিকভাবে পাই তবে) হিসাবে সংজ্ঞায়িত করে ।
স্কিপি লে গ্র্যান্ড গৌড়ো 5'19

আমি এটি পাই না, কেন মিনি_ম্যাক্স স্কেলিংটিকে সাধারণীকরণ হিসাবে বিবেচনা করা হয়! স্বাভাবিকের গড় বণ্টন শূন্য এবং প্রকরণ 1 এর সাথে সাধারণ বন্টনের অর্থে অর্থ পাওয়া যায়
ওভারফ্লো পুলিশ

আপনি যদি ২০২০ বা তার পরে এই প্রশ্নটি দেখছেন, @ পডেলের উত্তর দেখুন, আপনি পান্ডাস বনাম স্ক্লারেন ব্যবহার করলে সাধারণীকরণের বিভিন্ন উত্তর পাবেন।
ভিশন পাউদেল

@ পাউডেল ddofযুক্তির কারণে এটি কি?
এফফ্রস্ট

উত্তর:


223

আপনি ডেটা স্বাভাবিক করার জন্য প্যাকেজ স্কলারন এবং এর সাথে সম্পর্কিত প্রিপ্রোসেসিং ইউটিলিটিগুলি ব্যবহার করতে পারেন।

import pandas as pd
from sklearn import preprocessing

x = df.values #returns a numpy array
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
df = pd.DataFrame(x_scaled)

আরও তথ্যের জন্য ডেটা প্রিপ্রোসেসিংয়ের বিষয়ে সাইকিট-লার ডকুমেন্টেশন দেখুন : একটি পরিসরে স্কেলিং বৈশিষ্ট্য।


46
আমি মনে করি এটি কলামের নামগুলি থেকে মুক্তি পাবে, এটি প্রথম কারণেই ডেটাফ্রেমগুলি ব্যবহার করা অপের অন্যতম কারণ হতে পারে।
পিটজ

47
এটি প্রথমে স্থানান্তর না করা ছাড়া কলামগুলি নয়, সারিগুলিকে সাধারণ করবে। প্রশ্নটি যা জিজ্ঞাসা করে তা করার জন্য:pd.DataFrame(min_max_scaler.fit_transform(df.T), columns=df.columns, index=df.index)
20'17

26
@ পিটজ কলামের নাম রাখতে, এই পোস্টটি দেখুন । মূলত এর সাথে শেষ লাইনটি প্রতিস্থাপন করুনdf=pandas.DataFrame(x_scaled, columns=df.columns)
আইজোসেফ

5
@ হবস এটি সঠিক নয়। স্যান্ডম্যানের কোডটি কলাম অনুসারে এবং প্রতি-কলামে সাধারণ করে তোলে। আপনি স্থানান্তর করলে আপনি ভুল ফলাফল পাবেন।
পেটিজুরিখ

8
@ পেটিজুরিচ দেখে মনে হচ্ছে স্যান্ডম্যান বা প্রবীণ তাদের কোড সংশোধন করেছেন। ); দুর্ভাগ্যবশত, এটা সম্ভব সঠিক মন্তব্য করতে
hobs

397

পান্ডাস ব্যবহার করে একটি সহজ উপায় : (এখানে আমি গড় স্বাভাবিককরণ ব্যবহার করতে চাই)

normalized_df=(df-df.mean())/df.std()

সর্বনিম্ন সর্বোচ্চ ব্যবহার করতে:

normalized_df=(df-df.min())/(df.max()-df.min())

সম্পাদনা করুন: কিছু উদ্বেগের সমাধান করার জন্য, বলতে হবে যে পান্ডগুলি উপরের কোডটিতে স্বয়ংক্রিয়ভাবে কলম্বন-ভিত্তিক ফাংশন প্রয়োগ করে।


16
আমার এটা ভাল লেগেছে. এটি সংক্ষিপ্ত, এটি ভাবপূর্ণ এবং এটি শিরোনামের তথ্য সংরক্ষণ করে। তবে আমি মনে করি আপনাকেও ডিনোমিনেটরে কমপক্ষে বিয়োগ করতে হবে।
পিটজ

6
আমি ভুল মনে করি না। আমার জন্য সুন্দরভাবে কাজ করে - আমার মনে হয় না () এবং স্টাডি () এর কাজ করার জন্য কোনও ডেটা ফ্রেম ফেরানো দরকার এবং আপনার ত্রুটির বার্তাটি বোঝায় না যে সেগুলি ডেটা ফ্রেম না হওয়া একটি সমস্যা।
স্ট্রান্ডটাশে

24
এটি কলাম ভিত্তিক স্বাভাবিককরণ নয়। এটি সামগ্রিকভাবে পুরো ম্যাট্রিক্সকে স্বাভাবিক করছে যা ভুল ফলাফল প্রদান করবে।
Nguai আল

6
আমার জন্যও সুন্দরভাবে কাজ করেছেন। @ নুগায়াল আপনি সম্ভবত একটি নমপি ম্যাট্রিক্সে চেষ্টা করে যাচ্ছেন যে ক্ষেত্রে আপনি যা বলেছিলেন ফলাফল হতে পারে। তবে পান্ডাস ডেটাফ্রেমগুলির জন্য, সর্বনিম্ন, সর্বোচ্চ, ... টি পদক্ষেপগুলি কলাম অনুসারে ডিফল্টরূপে প্রয়োগ হয়।
সহায়ক

1
আমি এটি খুব পছন্দ করি
আইজাক সিম

51

এই পোস্টের উপর ভিত্তি করে: /stats/70801/how-to-normalize-data-to-0-1-range

আপনি নিম্নলিখিতটি করতে পারেন:

def normalize(df):
    result = df.copy()
    for feature_name in df.columns:
        max_value = df[feature_name].max()
        min_value = df[feature_name].min()
        result[feature_name] = (df[feature_name] - min_value) / (max_value - min_value)
    return result

আপনার মানগুলি নেতিবাচক বা ইতিবাচক কিনা তা নিয়ে আপনাকে চিন্তিত হওয়ার দরকার নেই। এবং মানগুলি 0 থেকে 1 এর মধ্যে খুব ভালভাবে ছড়িয়ে দেওয়া উচিত।


8
ন্যূনতম এবং সর্বাধিক মানগুলি সমান হলে আপনার ডিনোমিনেটর 0 হয় এবং আপনি একটি NaN মান পাবেন careful
হৃশিকেশ ধুমাল

36

আপনার সমস্যাটি কলামগুলিতে অভিনীত একটি সাধারণ রূপান্তর:

def f(s):
    return s/s.max()

frame.apply(f, axis=0)

বা আরও বেশি সংশ্লেষ:

   frame.apply(lambda x: x/x.max(), axis=0)

2
lambdaএক উত্তম :-)
আবু শোয়েব

4
প্রশ্নটি কলাম অনুযায়ী নরমালাইজেশন হওয়ার কারণে এটি অক্ষ = 1 হওয়ার কথা নয়?
Nguai আল

না, থেকে ডক্স : axis [...] 0 or 'index': apply function to each column। ডিফল্টটি আসলে axis=0তাই এই ওয়ান-লাইনারটিকে আরও ছোট করা যেতে পারে :-) ধন্যবাদ @ এসটিএসএম।
jorijnsmit

30

আপনি যদি স্কলারন প্যাকেজটি ব্যবহার করতে চান তবে আপনি পান্ডা ব্যবহার করে কলাম এবং সূচির নামগুলি রাখতে locপারেন:

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler() 
scaled_values = scaler.fit_transform(df) 
df.loc[:,:] = scaled_values

27

সরল সুন্দর:

df["A"] = df["A"] / df["A"].max()
df["B"] = df["B"] / df["B"].max()
df["C"] = df["C"] / df["C"].max()

দুর্দান্ত এবং আমার মতে সেরা সমাধান!
ম্যাকিয়েজ এ বেদনারজ

6
দ্রষ্টব্য, এই ওপিতে [০.০] ব্যাপ্তি চেয়েছে এবং এই সমাধানটি [-1..1] এর ব্যাপ্তিতে স্কেল করে। অ্যারে দিয়ে এটি চেষ্টা করুন [-10, 10]
আলেকজান্ডার সোসনোভেসচেঙ্কো

3
পছন্দ করুন বাসিল মুসা ধরে নিচ্ছেন ওপির ম্যাট্রিক্স সর্বদা অ-নেতিবাচক থাকে, এজন্যই তিনি এই সমাধান দিয়েছেন। যদি কিছু কলামে নেতিবাচক প্রবেশ থাকে তবে এই কোডটি [-1,1] ব্যাপ্তিতে স্বাভাবিক হয় না। এটি অ্যারে দিয়ে চেষ্টা করুন [-5, 10] নেতিবাচক মানগুলির সাথে [0,1] এ স্বাভাবিক হওয়ার সঠিক df["A"] = (df["A"]-df["A"].min()) / (df["A"].max()-df["A"].min())
উপায়টি সিনার

সহজ এবং স্পষ্ট
joshi123

সম্ভবত এমনকি সহজ: df /= df.max()- লক্ষ্য ধরে নেওয়া হয় প্রতিটি স্তম্ভকে পৃথকভাবে স্বাভাবিক করা।
n1k31t4

24

আপনি কলামগুলির একটি তালিকা তৈরি করতে পারেন যা আপনি সাধারণ করতে চান

column_names_to_normalize = ['A', 'E', 'G', 'sadasdsd', 'lol']
x = df[column_names_to_normalize].values
x_scaled = min_max_scaler.fit_transform(x)
df_temp = pd.DataFrame(x_scaled, columns=column_names_to_normalize, index = df.index)
df[column_names_to_normalize] = df_temp

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


তবে , আপনি যদি বিপরীতে চান তবে কলামগুলির একটি তালিকা নির্বাচন করুন যা আপনি সাধারণ করতে চান না , আপনি কেবল সমস্ত কলামের একটি তালিকা তৈরি করতে পারেন এবং সেই অনাকাঙ্ক্ষিত অপসারণ করতে পারেন

column_names_to_not_normalize = ['B', 'J', 'K']
column_names_to_normalize = [x for x in list(df) if x not in column_names_to_not_normalize ]

11

আমি মনে করি যে পান্ডসে এটি করার একটি আরও ভাল উপায় কেবলমাত্র

df = df/df.max().astype(np.float64)

সম্পাদনা করুন যদি আপনার ডেটা ফ্রেমে নেতিবাচক সংখ্যা উপস্থিত থাকে তবে আপনার পরিবর্তে ব্যবহার করা উচিত

df = df/df.loc[df.abs().idxmax()].astype(np.float64)

1
যদি কোনও কলামের সমস্ত মান শূন্য হয় তবে এটি কার্যকর হবে না
আহজিব

সর্বাধিক দ্বারা বর্তমান মানটি ভাগ করা কমপক্ষে 0 না হওয়া পর্যন্ত আপনাকে একটি সঠিক স্বাভাবিককরণ দেবে না
পিটিজ

আমি সম্মত, তবে এটি ওটি যা চেয়েছিল (তার উদাহরণ দেখুন)
ড্যানিয়েল

11

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

এই ধরণের সমস্যার আমার সমাধানটি নিম্নলিখিত:

 from sklearn import preprocesing
 x = pd.concat([df.Numerical1, df.Numerical2,df.Numerical3])
 min_max_scaler = preprocessing.MinMaxScaler()
 x_scaled = min_max_scaler.fit_transform(x)
 x_new = pd.DataFrame(x_scaled)
 df = pd.concat([df.Categoricals,x_new])

2
এই উত্তরটি দরকারী কারণ ইন্টারনেটে বেশিরভাগ উদাহরণগুলি সমস্ত কলামে একটি স্কেলার প্রয়োগ করে, যেখানে এটি আসলে সেই পরিস্থিতিকে সম্বোধন করে যেখানে একটি স্কেলার, মিনম্যাক্সস্কেলার বলে, সমস্ত কলামে প্রয়োগ করা উচিত নয়।
demongolem

10

পাইথনে বিভিন্ন মানককরণের উদাহরণ।

এই উইকিপিডিয়া নিবন্ধটি রেফারেন্সের জন্য দেখুন: https://en.wikedia.org/wiki/Unbiased_estiration_of_standard_deedia

উদাহরণ ডেটা

import pandas as pd
df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
               'C':list('abc')
             })
print(df)
   A    B  C
0  1  100  a
1  2  300  b
2  3  500  c

পান্ডা ব্যবহার করে সাধারণকরণ (নিরপেক্ষ অনুমান দেয়)

স্বাভাবিক করার সময় আমরা কেবলমাত্র গড়টি বিয়োগ করি এবং মান বিচ্যুতি দ্বারা ভাগ করি by

df.iloc[:,0:-1] = df.iloc[:,0:-1].apply(lambda x: (x-x.mean())/ x.std(), axis=0)
print(df)
     A    B  C
0 -1.0 -1.0  a
1  0.0  0.0  b
2  1.0  1.0  c

স্কেলার্ন ব্যবহার করে সাধারণকরণ (পক্ষপাতদুষ্ট অনুমান দেয়, পান্ডার থেকে পৃথক)

আপনি যদি একই জিনিসটি দিয়ে থাকেন তবে ভিন্ন ভিন্ন sklearnআউটপুট পাবেন!

import pandas as pd

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()


df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
               'C':list('abc')
             })
df.iloc[:,0:-1] = scaler.fit_transform(df.iloc[:,0:-1].to_numpy())
print(df)
          A         B  C
0 -1.224745 -1.224745  a
1  0.000000  0.000000  b
2  1.224745  1.224745  c

স্কেলার্নের বায়াসড অনুমানগুলি কি মেশিন লার্নিংকে কম শক্তিশালী করে তোলে?

কোন।

Sklearn.preprocessing.scale এর অফিসিয়াল ডকুমেন্টেশন বলছে যে মেশিন লার্নিং অ্যালগরিদমের কার্যকারিতা প্রভাবিত করার জন্য পক্ষপাতদুষ্ট অনুমানকারীটি ব্যবহার করা অনন্য। এবং আমরা সেগুলি নিরাপদে ব্যবহার করতে পারি।

From official documentation:
We use a biased estimator for the standard deviation,
equivalent to numpy.std(x, ddof=0). 
Note that the choice of ddof is unlikely to affect model performance.

মিনম্যাক্স স্কেলিংয়ের কী হবে?

মিনিম্যাক্স স্কেলিংয়ে কোনও স্ট্যান্ডার্ড বিচ্যুতি গণনা নেই। সুতরাং ফলাফল উভয় পান্ডা এবং সাইকিট-শিখায় সমান।

import pandas as pd
df = pd.DataFrame({
               'A':[1,2,3],
               'B':[100,300,500],
             })
(df - df.min()) / (df.max() - df.min())
     A    B
0  0.0  0.0
1  0.5  0.5
2  1.0  1.0


# Using sklearn
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler() 
arr_scaled = scaler.fit_transform(df) 

print(arr_scaled)
[[0.  0. ]
 [0.5 0.5]
 [1.  1. ]]

df_scaled = pd.DataFrame(arr_scaled, columns=df.columns,index=df.index)
print(df_scaled)
     A    B
0  0.0  0.0
1  0.5  0.5
2  1.0  1.0

6

আপনি কিছু কলামকে সাধারণীকরণ করতে চান এবং অন্যগুলি কিছুটা রিগ্রেশন টাস্কের মতো অপরিবর্তিত থাকতে চান যা ডেটা লেবেল বা শ্রেণীবদ্ধ কলামগুলি অপরিবর্তিত থাকে তাই আমি আপনাকে এই অজগর উপায়টি প্রস্তাব করছি (এটি @shg এবং @ সিনা উত্তরগুলির সংমিশ্রণ):

features_to_normalize = ['A', 'B', 'C']
# could be ['A','B'] 

df[features_to_normalize] = df[features_to_normalize].apply(lambda x:(x-x.min()) / (x.max()-x.min()))

5

এটি কেবল সাধারণ গণিত। উত্তর নীচের মত সহজ হওয়া উচিত।

normed_df = (df - df.min()) / (df.max() - df.min())

2
def normalize(x):
    try:
        x = x/np.linalg.norm(x,ord=1)
        return x
    except :
        raise
data = pd.DataFrame.apply(data,normalize)

পান্ডাসের নথি থেকে, ডেটাফ্রেম কাঠামো নিজেই একটি ক্রিয়াকলাপ (ফাংশন) প্রয়োগ করতে পারে।

DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)

ডেটাফ্রেমের ইনপুট অক্ষের সাথে ফাংশন প্রয়োগ করে। ফাংশনে পাস করা অবজেক্টগুলি হ'ল ডেটাফ্রেমের সূচক (অক্ষ = 0) বা কলামগুলি (অক্ষ = 1) দ্বারা সূচকযুক্ত সিরিজ অবজেক্ট। রিটার্নের ধরণটি পাস করা ফাংশন সমষ্টি কিনা, বা ডেটাফ্রেম খালি থাকলে আর্গুমেন্ট হ্রাস করে।

আপনি ডেটা ফ্রেম পরিচালনা করতে একটি কাস্টম ফাংশন প্রয়োগ করতে পারেন।


2
এটি ব্যাখ্যা করা ভাল হবে, কেন আপনার কোডটি ওপিএস সমস্যার সমাধান করে, তাই লোকেরা কেবল আপনার কোডটি অনুলিপি করার পরিবর্তে কৌশলটি মানিয়ে নিতে পারে। দয়া করে পড়ুন আমি কীভাবে একটি ভাল উত্তর লিখতে পারি?
মিঃ টি

2

নিম্নলিখিত ফাংশনটি জেড স্কোর গণনা করে:

def standardization(dataset):
  """ Standardization of numeric fields, where all values will have mean of zero 
  and standard deviation of one. (z-score)

  Args:
    dataset: A `Pandas.Dataframe` 
  """
  dtypes = list(zip(dataset.dtypes.index, map(str, dataset.dtypes)))
  # Normalize numeric columns.
  for column, dtype in dtypes:
      if dtype == 'float32':
          dataset[column] -= dataset[column].mean()
          dataset[column] /= dataset[column].std()
  return dataset

2

আপনি কীভাবে তালিকা বোধগম্যতাটি ব্যবহার করে এটি কলাম-ভিত্তিতে করেন:

[df[col].update((df[col] - df[col].min()) / (df[col].max() - df[col].min())) for col in df.columns]

1

আপনি সহজেই এইভাবে প্যান্ডাস ব্যবহার করতে পারেন ata ডেটা ফ্রেম.ট্রান্সফর্ম 1 ফাংশন:

df.transform(lambda x: x/x.max())

সমস্ত মান negativeণাত্মক হলে এই সমাধান কাজ করবে না। [-1, -2, -3] বিবেচনা করুন। আমরা -1 দ্বারা বিভক্ত, এবং এখন আমাদের [1,2,3] হয়েছে।
ডেভ লিউ


0

আপনি এক লাইনে এটি করতে পারেন

DF_test = DF_test.sub(DF_test.mean(axis=0), axis=1)/DF_test.mean(axis=0)

এটি প্রতিটি কলামের জন্য অর্থ নেয় এবং তারপরে প্রতিটি সারি থেকে এটি (গড়) বিয়োগ করে (নির্দিষ্ট কলামটির গড়টি কেবল তার সারি থেকে বিয়োগ করে) এবং কেবলমাত্র ভাগ করে দেয়। পরিশেষে, আমরা যা পাই তা হ'ল নরমালাইজড ডেটা সেট।


0

পান্ডস ডিফল্টরূপে কলাম অনুসারে নরমালাইজেশন করেন। নীচের কোড ব্যবহার করে দেখুন।

X= pd.read_csv('.\\data.csv')
X = (X-X.min())/(X.max()-X.min())

আউটপুট মানগুলি 0 এবং 1 এর মধ্যে থাকবে।

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