পাইথন পান্ডাসে কীভাবে একটি কলামের dtype চেক করবেন


130

সংখ্যার কলাম এবং স্ট্রিং কলামগুলি চিকিত্সা করতে আমার বিভিন্ন ফাংশন ব্যবহার করতে হবে। আমি এখন যা করছি তা সত্যিই বোবা:

allc = list((agg.loc[:, (agg.dtypes==np.float64)|(agg.dtypes==np.int)]).columns)
for y in allc:
    treat_numeric(agg[y])    

allc = list((agg.loc[:, (agg.dtypes!=np.float64)&(agg.dtypes!=np.int)]).columns)
for y in allc:
    treat_str(agg[y])    

এটি করার জন্য আরও কি মার্জিত উপায় আছে? যেমন

for y in agg.columns:
    if(dtype(agg[y]) == 'string'):
          treat_str(agg[y])
    elif(dtype(agg[y]) != 'string'):
          treat_numeric(agg[y])

2
stringকোনও টাইপ নয়
ডেভিড রবিনসন

উত্তর:


123

আপনি এর সাথে কলামের ডেটা-ধরণের অ্যাক্সেস করতে পারেন dtype:

for y in agg.columns:
    if(agg[y].dtype == np.float64 or agg[y].dtype == np.int64):
          treat_numeric(agg[y])
    else:
          treat_str(agg[y])

1
হাই ডেভিড, আপনি কেন == এনপি.ফ্লোয়াট 64 অন্তর্ভুক্ত করেছিলেন সে সম্পর্কে আপনি মন্তব্য করতে পারেন? আমরা কি ফ্লোটে রূপান্তর করার চেষ্টা করছি না? ধন্যবাদ।
রায়ান চেজ

@ রায়ানচেস এই প্রশ্নের ওপি কখনই বলেননি যে তিনি ভাসমানদের মধ্যে রূপান্তর করছেন, তাকে কেবল কোনও (অনির্দিষ্ট) treat_numericফাংশন ব্যবহার করবেন কিনা তা জানতে হবে । তিনি যেহেতু agg.dtypes==np.float64একটি বিকল্প হিসাবে অন্তর্ভুক্ত করেছিলেন, তাই আমিও করেছি।
ডেভিড রবিনসন

3
এই দুটিয়ের চেয়ে অল্প সংখ্যায় আরও বেশি সংখ্যক প্রকার রয়েছে, যা numberএখানে নীচে রয়েছে: docs.scipy.org/doc/numpy-1.13.0/references/arrays.scalars.html সাধারণ সমাধানটি হলis_numeric_dtype(agg[y])
আটটিলা তানয়ি

94

ইন pandas 0.20.2আপনি কি করতে পারেন:

from pandas.api.types import is_string_dtype
from pandas.api.types import is_numeric_dtype

is_string_dtype(df['A'])
>>>> True

is_numeric_dtype(df['B'])
>>>> True

সুতরাং আপনার কোড হয়ে যায়:

for y in agg.columns:
    if (is_string_dtype(agg[y])):
        treat_str(agg[y])
    elif (is_numeric_dtype(agg[y])):
        treat_numeric(agg[y])

1
পুরানো পান্ডাস সংস্করণগুলির কি কোনও বিকল্প আছে? আমি ত্রুটিটি পেয়েছি: এপিআই টাইপস নামে কোনও মডিউল নেই।
আরএফএফ

2
pandas.core.common.is_numeric_dtypeপান্ডা 0.13 সাল থেকে বিদ্যমান ছিল এবং এটি একই কাজ করে তবে এটি pandas.api.types.is_numeric_dtype0.19 এর পক্ষে
অবমূল্যায়ন করা হয়েছিল

এটি সর্বাধিক স্থানীয় উত্তর। তবে এখানে কিছু সতর্কতা অবলম্বন করা উচিত ।
09

46

আমি জানি এটি একটি পুরানো থ্রেডের কিছুটা হলেও প্যান্ডাসের সাথে 19.02, আপনি এটি করতে পারেন:

df.select_dtypes(include=['float64']).apply(your_function)
df.select_dtypes(exclude=['string','object']).apply(your_other_function)

http://pandas.pydata.org/pandas-docs/version/0.19.2/generated/pandas.DataFrame.select_dtypes.html


1
প্রথম উত্তরের জন্য এবং দ্বিতীয় লাইনের জন্য আমি সম্ভবত include[np.number]( ইনটস এবং 32 বিট ফ্লোটগুলি অন্তর্ভুক্ত করার জন্য) করব exclude[object]। স্ট্রিংগুলি অবধি ডাইপাইপের সাথে সম্পর্কিত objects আসলে, বস্তুর সাথে 'স্ট্রিং' অন্তর্ভুক্ত করা আমাকে ত্রুটি দেয়।
জন

1
মনে হচ্ছে "স্ট্রিং" আর সমর্থিত নয়, পরিবর্তে "অবজেক্ট" ব্যবহার করা উচিত। তবে অবশ্যই সঠিক উত্তর :)
বারট্রান্ড

এছাড়াও খেয়াল করা উচিত যে 'period'dtype আপাতত উত্থাপন NotImplementedErrorকরছে (প্যান্ডাস 0.24.2)। সুতরাং কারও কারও হাতে তৈরি পোস্ট প্রসেসিংয়ের প্রয়োজন থাকতে পারে।
ফ্লাইট

21

জিজ্ঞাসিত প্রশ্নের শিরোনাম সাধারণ, তবে লেখকরা প্রশ্নের শিরোনামে বর্ণিত কেসটি সুনির্দিষ্টভাবে ব্যবহার করেন। সুতরাং অন্য কোনও উত্তর ব্যবহার করা যেতে পারে।

তবে শিরোনাম প্রশ্নের পুরোপুরি উত্তর দেওয়ার জন্য এটি স্পষ্ট করে বলা উচিত যে দেখে মনে হচ্ছে যে সমস্ত পদ্ধতির কোনও কোনও ক্ষেত্রে ব্যর্থ হতে পারে এবং কিছু পুনরায় কাজ করা প্রয়োজন। আমি নির্ভরযোগ্যতা ক্রম হ্রাস করার জন্য তাদের সমস্ত (এবং কিছু অতিরিক্ত) পর্যালোচনা করেছি (আমার মতে):

1. সরাসরি ==(গ্রহণযোগ্য উত্তর) মাধ্যমে প্রকারের সাথে তুলনা করা ।

এটি উত্তর গৃহীত হয়েছে এবং সর্বাধিক উন্নত গণনা রয়েছে সত্ত্বেও, আমি মনে করি এই পদ্ধতিটি মোটেই ব্যবহার করা উচিত নয়। কারণ প্রকৃতপক্ষে এখানে বহুবার উল্লিখিত হিসাবে অ্যাসথনে এই পদ্ধতিকে নিরুৎসাহিত করা হয়েছে
কিন্তু যদি এক এখনও এটি ব্যবহার করতে চান - মত কিছু পান্ডাস-নির্দিষ্ট dtypes সচেতন হওয়া উচিত pd.CategoricalDType, pd.PeriodDtypeঅথবা pd.IntervalDtypetype( )টাইপটি সঠিকভাবে সনাক্ত করতে এখানে অতিরিক্ত ব্যবহার করতে হবে:

s = pd.Series([pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')])
s
s.dtype == pd.PeriodDtype   # Not working
type(s.dtype) == pd.PeriodDtype # working 

>>> 0    2002-03-01
>>> 1    2012-02-01
>>> dtype: period[D]
>>> False
>>> True

এখানে আরেকটি সতর্কতাই হ'ল এই ধরণেরটি নির্দিষ্টভাবে উল্লেখ করা উচিত:

s = pd.Series([1,2])
s
s.dtype == np.int64 # Working
s.dtype == np.int32 # Not working

>>> 0    1
>>> 1    2
>>> dtype: int64
>>> True
>>> False

2. isinstance()পদ্ধতির।

এই পদ্ধতিটি এখনও পর্যন্ত উত্তরে উল্লেখ করা হয়নি।

সুতরাং প্রকারের সাথে সরাসরি তুলনা করা যদি ভাল ধারণা না হয় - তবে এই উদ্দেশ্যে স্বতন্ত্র পাইথন ফাংশনটি চেষ্টা করে দেখি - isinstance()
এটা ঠিক শুরুতে ব্যর্থ হয়, কারণ ধরে নেয় যে আমরা কিছু বস্তু আছে, কিন্তু pd.Seriesবা pd.DataFrameপূর্বনির্ধারিত কেবল খালি পাত্রে হিসাবে ব্যবহার করা যেতে পারে dtypeকিন্তু এটা কোন বস্তু:

s = pd.Series([], dtype=bool)
s

>>> Series([], dtype: bool)

তবে যদি কেউ কোনওভাবে এই সমস্যাটি অতিক্রম করে এবং প্রতিটি বস্তু অ্যাক্সেস করতে চায়, উদাহরণস্বরূপ, প্রথম সারিতে এবং এর টাইপটি এর মতো কিছু পরীক্ষা করে:

df = pd.DataFrame({'int': [12, 2], 'dt': [pd.Timestamp('2013-01-02'), pd.Timestamp('2016-10-20')]},
                  index = ['A', 'B'])
for col in df.columns:
    df[col].dtype, 'is_int64 = %s' % isinstance(df.loc['A', col], np.int64)

>>> (dtype('int64'), 'is_int64 = True')
>>> (dtype('<M8[ns]'), 'is_int64 = False')

এটি একক কলামে মিশ্রিত ধরণের ডেটার ক্ষেত্রে বিভ্রান্তিকর হবে:

df2 = pd.DataFrame({'data': [12, pd.Timestamp('2013-01-02')]},
                  index = ['A', 'B'])
for col in df2.columns:
    df2[col].dtype, 'is_int64 = %s' % isinstance(df2.loc['A', col], np.int64)

>>> (dtype('O'), 'is_int64 = False')

এবং শেষ কিন্তু সর্বনিম্ন নয় - এই পদ্ধতিটি সরাসরি Categoryটাইপকে চিনতে পারে না । দস্তাবেজে যেমন বলা হয়েছে :

শ্রেণীবদ্ধ তথ্য থেকে একটি আইটেম ফেরত মান "1" দৈর্ঘ্যের শ্রেণীবদ্ধ নয়, মান প্রদান করবে।

df['int'] = df['int'].astype('category')
for col in df.columns:
    df[col].dtype, 'is_int64 = %s' % isinstance(df.loc['A', col], np.int64)

>>> (CategoricalDtype(categories=[2, 12], ordered=False), 'is_int64 = True')
>>> (dtype('<M8[ns]'), 'is_int64 = False')

সুতরাং এই পদ্ধতিটি প্রায় অগ্রহণযোগ্য।

3. df.dtype.kindপদ্ধতির।

এই পদ্ধতি এখনো খালি সাথে কাজ করতে পারে pd.Seriesবা pd.DataFramesঅন্য সমস্যা রয়েছে।

প্রথম - এটি কিছু টাইপগুলি পৃথক করতে অক্ষম:

df = pd.DataFrame({'prd'  :[pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')],
                   'str'  :['s1', 's2'],
                   'cat'  :[1, -1]})
df['cat'] = df['cat'].astype('category')
for col in df:
    # kind will define all columns as 'Object'
    print (df[col].dtype, df[col].dtype.kind)

>>> period[D] O
>>> object O
>>> category O

দ্বিতীয়ত, আমার জন্য কি আসলে এখনো স্পষ্ট নয়, এটা এমন কিছু dtypes আয় কোনটি

4. df.select_dtypesপদ্ধতির।

এটি আমরা যা চাই প্রায় এটিই। এই পদ্ধতিটি পান্ডার ভিতরে নকশা করা হয়েছে যাতে এটি পূর্বে উল্লিখিত বেশিরভাগ কোণার কেসগুলি পরিচালনা করে - খালি ডেটাফ্রেমগুলি, আঙ্কুল বা পান্ডাস-নির্দিষ্ট ধরণের টাইপের চেয়ে আলাদা। এটি সিঙ্গল টাইপের মতো ভালো কাজ করে .select_dtypes('bool')। এটি টাইপয়ের উপর ভিত্তি করে কলামগুলির গোষ্ঠীগুলি নির্বাচনের জন্যও ব্যবহার করা যেতে পারে:

test = pd.DataFrame({'bool' :[False, True], 'int64':[-1,2], 'int32':[-1,2],'float': [-2.5, 3.4],
                     'compl':np.array([1-1j, 5]),
                     'dt'   :[pd.Timestamp('2013-01-02'), pd.Timestamp('2016-10-20')],
                     'td'   :[pd.Timestamp('2012-03-02')- pd.Timestamp('2016-10-20'),
                              pd.Timestamp('2010-07-12')- pd.Timestamp('2000-11-10')],
                     'prd'  :[pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')],
                     'intrv':pd.arrays.IntervalArray([pd.Interval(0, 0.1), pd.Interval(1, 5)]),
                     'str'  :['s1', 's2'],
                     'cat'  :[1, -1],
                     'obj'  :[[1,2,3], [5435,35,-52,14]]
                    })
test['int32'] = test['int32'].astype(np.int32)
test['cat'] = test['cat'].astype('category')

ডক্সগুলিতে যেমন বলা হয়েছে তেমন :

test.select_dtypes('number')

>>>     int64   int32   float   compl   td
>>> 0      -1      -1   -2.5    (1-1j)  -1693 days
>>> 1       2       2    3.4    (5+0j)   3531 days

অন ​​ভাবতে পারে যে এখানে আমরা প্রথম অপ্রত্যাশিত দেখতে পাই (আমার জন্য ব্যবহৃত: প্রশ্ন ) ফলাফল - TimeDeltaআউটপুটে অন্তর্ভুক্ত DataFrame। বিপরীতে উত্তর হিসাবে এটি যেমন হওয়া উচিত, কিন্তু এক এটি সচেতন হতে হবে। লক্ষ্য করুন boolএড়ানো dtype, যে এছাড়াও কারো জন্য অবাঞ্ছিত হতে পারে, কিন্তু এটি কারণে boolএবং numberভিন্ন "হয় সাব-ট্রি numpy dtypes এর"। বুলের ক্ষেত্রে আমরা test.select_dtypes(['bool'])এখানে ব্যবহার করতে পারি।

এই পদ্ধতির পরবর্তী সীমাবদ্ধতাটি হ'ল পান্ডার বর্তমান সংস্করণে (0.24.2), এই কোড: test.select_dtypes('period')উত্থাপন করবে NotImplementedError

এবং আরেকটি বিষয় হ'ল এটি অন্যান্য বস্তুর থেকে স্ট্রিংয়ের পার্থক্য করতে অক্ষম:

test.select_dtypes('object')

>>>     str     obj
>>> 0    s1     [1, 2, 3]
>>> 1    s2     [5435, 35, -52, 14]

তবে এটি হ'ল প্রথম - ডক্সে ইতিমধ্যে উল্লিখিত । এবং দ্বিতীয় - এই পদ্ধতির সমস্যা নয়, বরং স্ট্রিংগুলি যেভাবে সংরক্ষণ করা হয় DataFrame। তবে যাইহোক এই ক্ষেত্রে কিছু পোস্ট প্রসেসিং থাকতে হবে।

5. df.api.types.is_XXX_dtypeপদ্ধতির।

আমার ধারণা হিসাবে এটি একটাই ধরণের এবং স্বীকৃতি অর্জনের সবচেয়ে শক্তিশালী এবং দেশীয় উপায় (মডিউলটির পথ যেখানে ফাংশনগুলি থাকে সেগুলি নিজেই বলে) এবং এটি প্রায় নিখুঁতভাবে কাজ করে তবে তারপরেও কমপক্ষে একটি ক্যাভেট রয়েছে এবং এখনও স্ট্রিং কলামগুলিকে আলাদা করতে হবে

এছাড়াও, এটি বিষয়গত হতে পারে তবে এই পদ্ধতির সাথে আরও 'মানব-বোধগম্য' numberটাইপ গ্রুপ প্রসেসিংয়ের তুলনা রয়েছে .select_dtypes('number'):

for col in test.columns:
    if pd.api.types.is_numeric_dtype(test[col]):
        print (test[col].dtype)

>>> bool
>>> int64
>>> int32
>>> float64
>>> complex128

না timedeltaএবং boolঅন্তর্ভুক্ত করা হয়। পারফেক্ট।

আমার পাইপলাইন সময়ের এই মুহুর্তে ঠিক এই কার্যকারিতাটি ব্যবহার করে, পোস্ট হ্যান্ড প্রসেসিংয়ের একটি বিট।

আউটপুট।

আশা করি আমি মূল বিষয়টিতে তর্ক করতে সক্ষম হয়েছি - যে সমস্ত আলোচিত পন্থা ব্যবহার করা যেতে পারে তবে কেবল pd.DataFrame.select_dtypes()এবং pd.api.types.is_XXX_dtypeপ্রয়োগযোগ্য হিসাবে সত্যই বিবেচনা করা উচিত।


1
দুর্দান্ত এবং ভাল সূচিত উত্তর। :-)
অলিভার

7

আপনি যদি কোনও স্ট্রিং হিসাবে ডেটাফ্রেম কলামের ধরণের চিহ্ন চিহ্নিত করতে চান তবে আপনি এটি করতে পারেন:

df['A'].dtype.kind

একটি উদাহরণ:

In [8]: df = pd.DataFrame([[1,'a',1.2],[2,'b',2.3]])
In [9]: df[0].dtype.kind, df[1].dtype.kind, df[2].dtype.kind
Out[9]: ('i', 'O', 'f')

আপনার কোডের উত্তর:

for y in agg.columns:
    if(agg[y].dtype.kind == 'f' or agg[y].dtype.kind == 'i'):
          treat_numeric(agg[y])
    else:
          treat_str(agg[y])

4

কলামের ডেটা প্রকারগুলি প্রিন্ট করতে

ডেটা ধরণের পরে পরীক্ষা করতে উদাহরণস্বরূপ, একটি ফাইল থেকে একটি আমদানি

def printColumnInfo(df):
    template="%-8s %-30s %s"
    print(template % ("Type", "Column Name", "Example Value"))
    print("-"*53)
    for c in df.columns:
        print(template % (df[c].dtype, c, df[c].iloc[1]) )

দৃষ্টান্তমূলক আউটপুট:

Type     Column Name                    Example Value
-----------------------------------------------------
int64    Age                            49
object   Attrition                      No
object   BusinessTravel                 Travel_Frequently
float64  DailyRate                      279.0
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.