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




pandas coercion (4)

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

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

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

এবং এখন, Series কেবল একটি একক dtype । এইভাবে float সংযোগ।

পরিবর্তে কাঠামো pandas.pydata.org/pandas-docs/stable/reference/api/… হিসাবে pandas.pydata.org/pandas-docs/stable/reference/api/… ,

>>> 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 ব্যবহার করুন 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

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

উদাহরণস্বরূপ, এখানে int মতো int এবং b সহ a সাধারণ ডেটা ফ্রেম রয়েছে:

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

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


কিছু খনন করার পরে, এখানে কিছু মারাত্মক কুৎসিত 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

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


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

  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

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

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

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

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

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

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




coercion