সারিগুলি ইনডেক্সিং এবং whileোকানোর সময় পান্ডাস ডেটা ফ্রেমের জোরকে আটকাতে হবে


16

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

উদাহরণস্বরূপ, এখানে একটি সহজ ডাটা ফ্রেম হয় aযেমন intএবং bহিসাবে float:

import pandas as pd
pd.__version__  # '0.25.2'

df = pd.DataFrame({'a': [1], 'b': [2.2]})
print(df)
#    a    b
# 0  1  2.2
print(df.dtypes)
# a      int64
# b    float64
# dtype: object

এক সারি ইনডেক্স করার সময় এখানে একটি জবরদস্তির সমস্যা রয়েছে:

print(df.loc[0])
# a    1.0
# b    2.2
# Name: 0, dtype: float64
print(dict(df.loc[0]))
# {'a': 1.0, 'b': 2.2}

এবং এখানে একটি সারি সন্নিবেশ করার সময় একটি জবরদস্তির সমস্যা রয়েছে:

df.loc[1] = {'a': 5, 'b': 4.4}
print(df)
#      a    b
# 0  1.0  2.2
# 1  5.0  4.4
print(df.dtypes)
# a    float64
# b    float64
# dtype: object

উভয় ক্ষেত্রেই, আমি aকলামটি একটি ভাসমান ধরণের কাছে জোর না করে পূর্ণসংখ্যা টাইপ হিসাবে থাকতে চাই ।


আমি দেখেছি এই , কিন্তু আমি পাওয়া যেত কার্যকরভাবে সমস্যা সমাধান করা হয়েছে। মাঝামাঝি সময়ে আমি অনুমান করতে পারি যে আপনি করতে পারেন:df.loc[[0], df.columns]
দানি মেসেজো


Pd.DataFrame এর মতো শব্দগুলি ইনস্ট্যান্টেশনে টাইপ মিক্সিং সমর্থন করে না? pandas.pydata.org/pandas-docs/stable/references/api/… dtype পরম কেবল একটি একক প্রকারকে সমর্থন করে। .read_[type]যদিও একাধিক টাইপ সমর্থন করে ...
কুইন্টিন

উত্তর:


4

কিছু খনন করার পরে, এখানে কিছু মারাত্মক কুৎসিত workaround রয়েছে। (আরও ভাল উত্তর গৃহীত হবে))

এখানে একটি স্পর্শ পাওয়া যায় যে অ-সংখ্যাসূচক কলামগুলি জবরদস্তি থামিয়ে দেয়, সুতরাং এখানে একটি সারিকে কীভাবে সূচী করা যায় dict:

dict(df.assign(_='').loc[0].drop('_', axis=0))
# {'a': 1, 'b': 2.2}

এবং একটি সারি সন্নিবেশ করাতে একটি সারি সহ একটি নতুন ডেটা ফ্রেম তৈরি করে করা যেতে পারে:

df = df.append(pd.DataFrame({'a': 5, 'b': 4.4}, index=[1]))
print(df)
#    a    b
# 0  1  2.2
# 1  5  4.4

এই দুটি কৌশলই বড় ডেটা ফ্রেমের জন্য অনুকূলিত নয়, তাই আমি আরও ভাল উত্তরটির প্রশংসা করব!


আপনি সবসময় কেবল পোস্ট সংযোজন করতে বাধ্য করতে পারেন df['a'] = df.a.astype(mytype)... এটি এখনও নোংরা এবং সম্ভবত দক্ষ নয়।
কোয়ান্টিন

.astype()ভাসমান জন্য বিপজ্জনক -> পূর্ণসংখ্যা; এতে পরিবর্তন 1.1করতে কোনও সমস্যা নেই 1, সুতরাং আপনার সত্যিকারের সমস্ত মানগুলি এটি করার আগে 'পূর্ণসংখ্যার মতো' তা নিশ্চিত হওয়া দরকার। সম্ভবত সেরা ব্যবহার করতে pd.to_numericদিয়েdowncast='integer'
ALollz

2

সমস্যার মূলে এটি

  1. পান্ডাস ডেটাফ্রেমের সূচকে একটি পান্ডাস সিরিজ প্রদান করে

আমরা ওটা দেখতে পারি:

type(df.loc[0])
# pandas.core.series.Series

এবং সিরিজের কেবলমাত্র একটি টাইপ থাকতে পারে আপনার ক্ষেত্রে ইনটি 64 বা ফ্লোট 64।

আমার মাথায় দুটি কাজ রয়েছে

print(df.loc[[0]])
# this will return a dataframe instead of series
# so the result will be
#    a    b
# 0  1  2.2

# but the dictionary is hard to read
print(dict(df.loc[[0]]))
# {'a': 0    1
# Name: a, dtype: int64, 'b': 0    2.2
# Name: b, dtype: float64}

অথবা

print(df.astype(object).loc[0])
# this will change the type of value to object first and then print
# so the result will be
# a      1
# b    2.2
# Name: 0, dtype: object

print(dict(df.astype(object).loc[0]))
# in this way the dictionary is as expected
# {'a': 1, 'b': 2.2}
  1. আপনি যখন কোনও ডেটাফ্রেমে একটি অভিধান যুক্ত করবেন, এটি অভিধানটি প্রথমে একটি সিরিজে রূপান্তর করবে এবং তারপরে সংযোজন করবে। (সুতরাং একই সমস্যা আবার ঘটে)

https://github.com/pandas-dev/pandas/blob/master/pandas/core/frame.py#L6973

if isinstance(other, dict):
    other = Series(other)

সুতরাং আপনার ওয়াকারআউন্ডাউন্ডটি আসলে একটি শক্ত, অন্যথায় আমরা পারতাম:

df.append(pd.Series({'a': 5, 'b': 4.4}, dtype=object, name=1))
#    a    b
# 0  1  2.2
# 1  5  4.4

objectডেটা টাইপ ব্যবহার করার জন্য ভাল ধারণা ! আর একটি হ'ল প্রথম থেকে একটি অবজেক্ট ডেটাফ্রেম তৈরি করা:df = pd.DataFrame({'a': [1], 'b': [2.2]}, dtype=object)
মাইক টি

2

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

আপনি যখন df.loc[0]এটি রূপান্তর করেন pd.Series,

>>> type(df.loc[0])
<class 'pandas.core.series.Series'>

এবং এখন, Seriesশুধুমাত্র একটি একক হবে dtype। এইভাবে জোর intকরা float

পরিবর্তে হিসাবে কাঠামো রাখা pd.DataFrame,

>>> type(df.loc[[0]])
<class 'pandas.core.frame.DataFrame'>

ফ্রেম হিসাবে প্রয়োজনীয় সারিটি নির্বাচন করুন এবং তারপরে রূপান্তর করুন dict

>>> df.loc[[0]].to_dict(orient='records')
[{'a': 1, 'b': 2.2}]

একইভাবে, একটি নতুন সারি যুক্ত করতে, পান্ডাস pd.DataFrame.appendফাংশন ব্যবহার করুন ,

>>> df = df.append([{'a': 5, 'b': 4.4}]) # NOTE: To append as a row, use []
   a    b
0  1  2.2
0  5  4.4

উপরের ফলে ধরণের রূপান্তর ঘটায় না,

>>> df.dtypes
a      int64
b    float64
dtype: object

বাহটি পেতে দ্বিতীয় বার এটি ব্লকটি পড়তে হয়েছিল। এটা খুব সূক্ষ্ম। আমি অতীতে যা করেছি তার থেকে এটি অনেক ভাল ... চূড়ান্ত ডাটাফ্রেমের মধ্য দিয়ে লুপ করুন এবং সঠিক ডেটা টাইপের সাথে মানগুলি পুনরায় সাইন করুন (হ্যাঁ আমি যা করলাম তা একটি ভয়াবহ সমাধান যা সত্যই স্কেল হবে না))
ভ্যানব্যান্টাম

1
উহু. আনন্দিত এটি helped @ ভ্যানবন্তম
বিষ্ণুদেব

1

সামান্য ডেটা ম্যানিপুলেশন সহ একটি পৃথক পদ্ধতি:

ধরুন আপনার কাছে অভিধানের একটি তালিকা রয়েছে (বা ডেটাফ্রেম)

lod=[{'a': [1], 'b': [2.2]}, {'a': [5], 'b': [4.4]}]

যেখানে প্রতিটি অভিধান একটি সারি উপস্থাপন করে (দ্বিতীয় অভিধানের তালিকাগুলি নোট করুন)। তারপরে আপনি এর মাধ্যমে সহজেই একটি ডেটাফ্রেম তৈরি করতে পারেন:

pd.concat([pd.DataFrame(dct) for dct in lod])
   a    b
0  1  2.2
0  5  4.4

এবং আপনি কলামের প্রকারগুলি বজায় রাখছেন। কনক্যাট দেখুন

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

pd.concat([df] + [pd.DataFrame(dct) for dct in lod])

0

প্রথম ক্ষেত্রে, আপনি সহজেই পূর্ণসংখ্যার ডেটা টাইপ দিয়ে কাজ করতে পারেন । সিরিজ নির্বাচন জোর করে না floatএবং মানগুলি একটি objectধারক মধ্যে স্থাপন করা হয় । এর পরে অভিধানটি যথাযথভাবে তৈরি করা হবে, এর অন্তর্নিহিত মান হিসাবে একটি হিসাবে সঞ্চিত np.int64

df = pd.DataFrame({'a': [1], 'b': [2.2]})
df['a'] = df['a'].astype('Int64')

d = dict(df.loc[0])
#{'a': 1, 'b': 2.2}

type(d['a'])
#numpy.int64

আপনার সিনট্যাক্সের সাহায্যে এটি প্রায়শই দ্বিতীয় কেসের ক্ষেত্রেও কাজ করে, তবে এটি আপকাস্ট করে object, তাই দুর্দান্ত নয়:

df.loc[1] = {'a': 5, 'b': 4.4}
#   a    b
#0  1  2.2
#1  5  4.4

df.dtypes
#a     object
#b    float64
#dtype: object

তবে, আমরা শেষে (একটি রেঞ্জইন্ডেক্স সহ) একটি সারি যুক্ত করার জন্য বাক্য গঠনতে একটি ছোট পরিবর্তন করতে পারি এবং এখন টাইপগুলি সঠিকভাবে মোকাবেলা করা হয়।

df = pd.DataFrame({'a': [1], 'b': [2.2]})
df['a'] = df['a'].astype('Int64')

df.loc[df.shape[0], :] = [5, 4.4]
#   a    b
#0  1  2.2
#1  5  4.4

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