পান্ডে খালি মান (সাদা স্থান) প্রতিস্থাপন NaN এর সাথে


150

আমি একটি পান্ডাস ডেটা ফ্রেমে সমস্ত মান সন্ধান করতে চাই যেখানে সাদা স্থান (যেকোন স্বেচ্ছাসেবী পরিমাণ) থাকে এবং সেই মানগুলি NaN এর সাথে প্রতিস্থাপন করে।

কোন ধারণা কীভাবে এটি উন্নত করা যায়?

মূলত আমি এটি চালু করতে চাই:

                   A    B    C
2000-01-01 -0.532681  foo    0
2000-01-02  1.490752  bar    1
2000-01-03 -1.387326  foo    2
2000-01-04  0.814772  baz     
2000-01-05 -0.222552         4
2000-01-06 -1.176781  qux     

এটিতে:

                   A     B     C
2000-01-01 -0.532681   foo     0
2000-01-02  1.490752   bar     1
2000-01-03 -1.387326   foo     2
2000-01-04  0.814772   baz   NaN
2000-01-05 -0.222552   NaN     4
2000-01-06 -1.176781   qux   NaN

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

for i in df.columns:
    df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None

খালি স্ট্রিং থাকতে পারে এমন ক্ষেত্রগুলির মধ্যে দিয়ে কেবল পুনরাবৃত্তি করে এটি কিছুটা অনুকূল করা যেতে পারে:

if df[i].dtype == np.dtype('object')

তবে এটি তেমন কোনও উন্নতি নয়

এবং পরিশেষে, এই কোডটি কোনওটির সাথে লক্ষ্যযুক্ত স্ট্রিংগুলি সেট করে, যা পান্ডসের মতো কাজ করে যেমন: fillna()তবে এটি সম্পূর্ণরূপে ভাল লাগবে যদি আমি আসলে NaNপরিবর্তে সরাসরি sertোকাতে পারি None


2
আপনি যা সত্যই চান তা হ'ল replaceএকটি রেজেক্সের সাহায্যে সক্ষম হোন ... (সম্ভবত এটি কোনও বৈশিষ্ট্য হিসাবে অনুরোধ করা উচিত)।
অ্যান্ডি হেডেন

3
আমি এই বৈশিষ্ট্যটির জন্য গিথুব ইস্যু করেছি: github.com/pydata/pandas/issues/2285 । PRs জন্য কৃতজ্ঞ হবে! :)
চ্যাং সে

যারা একেবারে একটি ফাঁকা চরিত্রটি গায়েব করতে চান তাদের নীচের এই সহজ সমাধানটি দেখুন
টেড পেট্রো

উত্তর:


198

আমি মনে করি df.replace()কাজটি কাজ করে, যেহেতু পান্ডাস 0.13 :

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

# replace field that's entirely space (or empty) with NaN
print(df.replace(r'^\s*$', np.nan, regex=True))

উত্পাদন:

                   A    B   C
2000-01-01 -0.532681  foo   0
2000-01-02  1.490752  bar   1
2000-01-03 -1.387326  foo   2
2000-01-04  0.814772  baz NaN
2000-01-05 -0.222552  NaN   4
2000-01-06 -1.176781  qux NaN

তেমনক যেমন এটি উল্লেখ করেছেন, df.replace(r'^\s+$', np.nan, regex=True)আপনার বৈধ ডেটাতে সাদা স্থান রয়েছে এমন ক্ষেত্রে ব্যবহার করুন ।


1
রেজেক্স হ'ল বুলিয়ান পতাকা। হতে পারে আপনার অর্থ pd.Series(["1", "#", "9", " .", None]).replace(r"( +\.)|#", "X", regex=True).valuesযা দেয়['1', 'X', '9', 'X', None]
প্যাট্রিকসুরি

2
2 বছর পরে, আমি এটির গ্রহণযোগ্য উত্তর পরিবর্তন করেছি, এখন যে পান্ডাস এটি সমর্থন করে। ধন্যবাদ!
ক্রিস ক্লার্ক

35
দ্রষ্টব্য : আপনি যদি না চান যে মাঝখানে স্থান রয়েছে এমন একটি উপাদান NaN ব্যবহারের সাথে প্রতিস্থাপন করা যায়df.replace(r'^\s+$', np.nan, regex=True)
তেমাক

7
আমি এটি ব্যবহারের চেষ্টা করেছি, কিন্তু জানতে পেরেছি যে '' * * s * $ 'ব্যবহার করার মত প্রকাশ হওয়া উচিত। ^ এবং without ছাড়াই এটি টানা দুটি ফাঁকা দিয়ে কোনও স্ট্রিংয়ের সাথে মেলে। NaN
মাস্টার ইয়োগার্ট

1
আমি আমার কোডটিতে আপনার সমাধানটি চেষ্টা করছি, তবে এর কোনও প্রভাব নেই। আমি "শক্তি [" শক্তি সরবরাহ "] চেষ্টা করছি replace প্রতিস্থাপন করুন (to_replace =" ... ", মান = np.NaN)"। "..." স্ট্রিংটি NaN মানগুলিতে পরিবর্তন করতে চাইলেও এটি কিছুই করে না এবং একই ডেটাফ্রেমটি ফেরত দেয়।
অর্চনা জোশী

50

আপনি যদি খালি খালি স্ট্রিং এবং রেকর্ডগুলি কেবল ফাঁকা জায়গায় প্রতিস্থাপন করতে চান তবে সঠিক উত্তরটি হ'ল ::

df = df.replace(r'^\s*$', np.nan, regex=True)

গৃহীত উত্তর

df.replace(r'\s+', np.nan, regex=True)

একটি খালি স্ট্রিং প্রতিস্থাপন করে না !, আপনি সামান্য আপডেট করা উদাহরণ দিয়ে নিজেকে চেষ্টা করতে পারেন:

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'fo o', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', ''],         
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

দ্রষ্টব্য, এছাড়াও যে 'ফো ও' নানের সাথে প্রতিস্থাপন করা হবে না, যদিও এতে একটি স্থান রয়েছে। আরও নোট, এটি একটি সহজ:

df.replace(r'', np.NaN)

হয় না কাজ করে - চেষ্টা করে দেখুন।


33

কেমন:

d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

applymapফাংশন dataframe প্রতিটি কক্ষের একটি ফাংশন প্রযোজ্য।


কি সুন্দর উন্নতি! আমার এইটাকে প্রিস্ট্রোস্পেক্টে ভাবতে হবে, তবে কোনও কারণে বুলিয়ান রিপ্লেসমেন্ট করাতে ঝুলতে হয়েছিল। একটি প্রশ্ন - বেস স্ট্রিং চেক বনাম কেবল টিআর (এক্স)। স্পেস () কি করার কোনও সুবিধা আছে?
ক্রিস ক্লার্ক

1
@ ক্রিসক্লার্ক: উভয়ই ভাল আছেন, যদিও আমি অনুমান করব যে এটি isinstanceকিছুটা দ্রুত হবে।
ব্রেনবার্ন

13
উপরের কোডে "বেসস্ট্রিং" এর উল্লেখটি পাইথন 3 তে কাজ করবে না .... সেক্ষেত্রে পরিবর্তে "স্ট্র" ব্যবহার করার চেষ্টা করুন।
স্পাইক উইলিয়ামস

4
নোট করুন যে এই সমাধানটি খালি স্ট্রিংগুলি প্রতিস্থাপন করে না ''। খালি স্ট্রিংগুলি বিবেচনা করতে, ব্যবহার করুন:d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and (not x or x.isspace()) else x)
tuomastik

18

আমি এটি করব:

df = df.apply(lambda x: x.str.strip()).replace('', np.nan)

অথবা

df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan)

আপনি সমস্ত স্ট্রিপ স্ট্রিপ করতে পারেন, তারপরে খালি আরআরটি প্রতিস্থাপন করতে পারেন np.nan


ল্যাম্বদা এক্স: x.str.strip () ল্যাম্বডা x: x.strip () হওয়া উচিত? সামান্য পরামর্শ: সামনে .astype (str) যুক্ত করুন, এটি আমার জন্য অন্যান্য ডেটা সমস্যা সমাধান করে। আমার জন্য এই কাজ করুন: df = df.apply [ 'কলামে'] astype (STR) .apply (ল্যামডা X: x.strip ()) প্রতিস্থাপন ( '',
Wouter

কোডের দ্বিতীয় লাইনটি ইন / ফ্লোট এবং স্ট্রিং টাইপ কলাম উভয়ই পরিচালনা করে। খুশী হলাম। Tks!
কেট স্টোহর


5

আপনি যদি সিএসভি ফাইল থেকে ডেটা রফতানি করে থাকেন তবে এটি এত সহজ হতে পারে:

df = pd.read_csv(file_csv, na_values=' ')

এটি ডেটা ফ্রেম তৈরি করার পাশাপাশি না হিসাবে ফাঁকা মান প্রতিস্থাপন করবে


2
আরেকটি বিকল্প..উজিং skipinitialspace=Trueডিলিমিটারের পরে যে কোনও সাদা স্থানকে সরিয়ে দেয় যার ফলে সাদা জায়গার যে কোনও দৈর্ঘ্য, খালি স্ট্রিংগুলি পড়তে হবে nan। তবে যদি আপনি কোনও কারণের জন্য প্রাথমিক স্পেসগুলি ধরে রাখতে চান তবে এই বিকল্পটি ভাল পছন্দ নয়।
রাজশেকার রেড্ডি

1
@ রাজেশেকেরেডি আপনি দয়া করে এটি উত্তর হিসাবে কোথাও রাখতে পারেন, এটি দুর্দান্ত ছিল!
ব্যবহারকারী 2321

2

খুব দ্রুত এবং সহজ সমাধানের জন্য যেখানে আপনি একক মানের তুলনায় সমতাটি পরীক্ষা করেন, আপনি maskপদ্ধতিটি ব্যবহার করতে পারেন ।

df.mask(df == ' ')

1

এগুলি সবই সঠিক উত্তরের নিকটবর্তী, তবে অন্যদের কাছে আপনার কোডটি পড়ার পক্ষে সবচেয়ে বেশি পাঠযোগ্য হয়ে ওঠার পরে আমি কোনও সমস্যার সমাধান বলব না। আমি বলব যে উত্তরটি ব্রেনবারনের উত্তর এবং সেই উত্তরের নীচে টিউমাস্টিকের মন্তব্যের সংমিশ্রণ । ব্রেনবারনের উত্তর অন্তর্নির্মিত ব্যবহার করে isspace, তবে ওপি অনুরোধ অনুসারে খালি স্ট্রিংগুলি সরিয়ে দেয়াকে সমর্থন করে না, এবং আমি নূরের সাথে স্ট্রিংগুলি প্রতিস্থাপনের স্ট্যান্ডার্ড ইউজ কেস হিসাবে এটির জন্য দায়ী করব।

আমি এটি দিয়ে আবার লিখেছি .apply, আপনি এটি একটি pd.Seriesবা কল করতে পারেন pd.DataFrame


পাইথন 3:

সম্পূর্ণ ফাঁকা স্থানগুলির খালি স্ট্রিং বা স্ট্রিং প্রতিস্থাপন করতে:

df = df.apply(lambda x: np.nan if isinstance(x, str) and (x.isspace() or not x) else x)

সম্পূর্ণ স্পেসগুলির স্ট্রিংগুলি প্রতিস্থাপন করতে:

df = df.apply(lambda x: np.nan if isinstance(x, str) and x.isspace() else x)

পাইথন 2 এ এটি ব্যবহার করতে, আপনার strসাথে প্রতিস্থাপন করতে হবে basestring

পাইথন 2:

সম্পূর্ণ ফাঁকা স্থানগুলির খালি স্ট্রিং বা স্ট্রিং প্রতিস্থাপন করতে:

df = df.apply(lambda x: np.nan if isinstance(x, basestring) and (x.isspace() or not x) else x)

সম্পূর্ণ স্পেসগুলির স্ট্রিংগুলি প্রতিস্থাপন করতে:

df = df.apply(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

1

এটি আমার পক্ষে কাজ করেছে। আমি যখন আমার সিএসভি ফাইল আমদানি করি তখন আমি na_values ​​= '' যুক্ত করেছিলাম। স্পেসগুলি ডিফল্ট NaN মানগুলিতে অন্তর্ভুক্ত থাকে না।

ডিএফ = পিডি.ড্রেড_সিএসভি (ফাইলপথ, না_মূল্য = '')


0

এটি করতে আপনি একটি ফিল্টারও ব্যবহার করতে পারেন।

df = PD.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],     
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '])
    df[df=='']='nan'
    df=df.astype(float)

এই কোডের প্রতিটি লাইন (ডেটা সহ নয়) ত্রুটিযুক্ত।
জুলিয়াস

0
print(df.isnull().sum()) # check numbers of null value in each column

modifiedDf=df.fillna("NaN") # Replace empty/null values with "NaN"

# modifiedDf = fd.dropna() # Remove rows with empty values

print(modifiedDf.isnull().sum()) # check numbers of null value in each column

0

এটি একটি মার্জিত সমাধান নয়, তবে যা কাজ করে বলে মনে হচ্ছে তা XLSX এ সঞ্চয় করা এবং তারপরে এটি আবার আমদানি করা। এই পৃষ্ঠার অন্যান্য সমাধানগুলি আমার পক্ষে কার্যকর হয়নি, কেন তা অনিশ্চিত।

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