पांडस कैसे एक श्रृंखला को फ़िल्टर करने के लिए


94

ग्रुपबी ('नाम') और दूसरे कॉलम पर माध्य () फ़ंक्शन का उपयोग करने के बाद मेरे पास इस तरह की एक श्रृंखला है

name
383      3.000000
663      1.000000
726      1.000000
737      9.000000
833      8.166667

क्या कोई मुझे बता सकता है कि 1.000000 माध्य मान वाली पंक्तियों को कैसे फ़िल्टर किया जाए? धन्यवाद और मैं आपकी मदद की बहुत सराहना करता हूं।


ठीक है, आप किसी दिए गए शर्त पर श्रृंखला को कैसे फ़िल्टर करेंगे?

जवाबों:


127
In [5]:

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s = s[s != 1]
s
Out[0]:
383    3.000000
737    9.000000
833    8.166667
dtype: float64

10
मैं नीचे दिए गए उत्तरों को पसंद करता हूं क्योंकि उन्हें जंजीर किया जा सकता है (अर्थात परिभाषित करने की आवश्यकता नहीं है sऔर फिर इसे अभिव्यक्ति में दो बार उपयोग करें)। केवल पांडा 0.18 से काम करता है।
आईएएनएस

इसके अलावा piRSquared के उत्तर में समय की तुलना देखें ।
17१ at को an

63

पांडा संस्करण से 0.18+ की श्रृंखला को छानकर नीचे भी किया जा सकता है

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

pd.Series(test).where(lambda x : x!=1).dropna()

चेकआउट: http://pandas.pydata.org/pandas-docs/version/0.18.1/whatsnew.html#method-chaininng-improvements


3
विधि श्रृंखलन के साथ इतना अच्छा है (और स्पार्क की याद दिलाता है।)
डायलन हॉग

सच है, लेकिन स्पार्क इस मामले में कुछ अधिक सहज है: यह बस उन पंक्तियों से छुटकारा पा लेता है जो विधेय से मेल नहीं खाती हैं, इसका मतलब है कि ".dropna ()" भाग का उपयोग करना जो स्पष्ट रूप से मेरे लिए स्पष्ट रूप से सतही लग रहा था जब तक कि मैंने डॉक्टर को नहीं पढ़ा। उसके द्वारा काट लिया गया: डी
फ्लोरेंट मोनी

44

जैसा कि DACW ने बताया , पांडा 0.18.1 में विधि- चांगिंग सुधार हैं जो आप बहुत अच्छी तरह से देख रहे हैं।

उपयोग करने के बजाय .where, आप अपने फ़ंक्शन को .locअनुक्रमणिका या श्रृंखला अनुक्रमणिका में पास कर सकते हैं []और कॉल से बच सकते हैं .dropna:

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.loc[lambda x : x!=1]

test[lambda x: x!=1]

इसी तरह के व्यवहार को DataFrame और NDFrame वर्गों पर समर्थन दिया जाता है।


2
यह मेरा पसंदीदा उत्तर है, और यह बिना खटास के नीचे जाने के लिए सबसे तेज़ प्रतीत होता है (समय की तुलना देखें)।
आईएएनएस

21

ऐसा करने का एक तेज़ तरीका numpyअंतर्निहित सरणियों को स्लाइस करने के लिए पुनर्निर्माण करना है। नीचे टाइमिंग देखें।

mask = s.values != 1
pd.Series(s.values[mask], s.index[mask])

0
383    3.000000
737    9.000000
833    8.166667
dtype: float64

भोले का समय

यहाँ छवि विवरण दर्ज करें


, मुझे आपकी विधि पसंद है, मुझे पता है कि अगर मेरे पास बहु-मुखौटे हैं तो मैं क्या करना चाहता हूं। Thx
मेंगलांग ली

1
@ मेनग्लाइली निर्भर करता है, आपको एक सवाल पूछना चाहिए। सबसे अधिक संभावना है, आप उन्हें साथ जोड़ देंगे। मास्क = मास्क 1 और मास्क 2
piRSquared

6

दूसरा तरीका यह है कि आप पहले एक DataFrame में कनवर्ट करें और क्वेरी विधि (यह मानकर कि आपके पास संकलित संस्थापित है) का उपयोग करें:

import pandas as pd

test = {
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
}

s = pd.Series(test)
s.to_frame(name='x').query("x != 1")

मुझे नहीं लगता है कि यह एक स्ट्रिंग के रूप में एक शर्त को पारित करने के लिए एक अच्छा विचार है
SzymonPajzert

1
यह डेटाफ़्रेम के सभी ओवरहेड को जोड़ता है, और बहुत धीमा होने वाला है।
काल्पनिक

5

यदि आपको एक जंजीर ऑपरेशन पसंद है, तो आप compressफ़ंक्शन का उपयोग भी कर सकते हैं :

test = pd.Series({
383:    3.000000,
663:    1.000000,
726:    1.000000,
737:    9.000000,
833:    8.166667
})

test.compress(lambda x: x != 1)

# 383    3.000000
# 737    9.000000
# 833    8.166667
# dtype: float64

1

मेरे मामले में मेरे पास एक पांडा श्रृंखला थी जहां मूल्य पात्रों के ट्यूपल्स हैं :

Out[67]
0    (H, H, H, H)
1    (H, H, H, T)
2    (H, H, T, H)
3    (H, H, T, T)
4    (H, T, H, H)

इसलिए मैं श्रृंखला को फ़िल्टर करने के लिए अनुक्रमणिका का उपयोग कर सकता हूं, लेकिन मुझे आवश्यक सूचकांक बनाने के लिए apply। मेरी शर्त है "सभी टुपल्स ढूंढें जिनमें बिल्कुल एक 'एच' है।"

series_of_tuples[series_of_tuples.apply(lambda x: x.count('H')==1)]

मैं मानता हूं कि यह "चेनेबल" नहीं है , (यानी नोटिस मैं series_of_tuplesदो बार दोहराता हूं ; आपको किसी भी अस्थायी श्रृंखला को एक चर में संग्रहित करना चाहिए ताकि आप उस पर लागू (...) कॉल कर सकें)।

अन्य तरीके भी हो सकते हैं (इसके अलावा .apply(...)) जो बूलियन इंडेक्स बनाने के लिए एलिमेंट वाइज संचालित कर सकते हैं।

कई अन्य उत्तर (स्वीकृत उत्तर सहित) श्रृंखलाबद्ध कार्यों का उपयोग कर जैसे:

  • .compress()
  • .where()
  • .loc[]
  • []

ये कॉलबल्स (लैम्ब्डा) को स्वीकार करते हैं जो श्रृंखला में लागू होते हैं , न कि उन श्रृंखलाओं में व्यक्तिगत मूल्यों के लिए !

इसलिए मेरी टुपल्स की श्रृंखला ने अजीब व्यवहार किया जब मैंने अपनी उपरोक्त स्थिति / कॉल करने योग्य / लैम्ब्डा का उपयोग करने का प्रयास किया, जैसे कि किसी भी श्रृंखलाबद्ध कार्य के साथ .loc[]:

series_of_tuples.loc[lambda x: x.count('H')==1]

त्रुटि उत्पन्न करता है:

KeyError: 'Level H को नाम (कोई नहीं) के समान होना चाहिए'

मैं बहुत उलझन में था, लेकिन यह Series.count series_of_tuples.count(...)फ़ंक्शन का उपयोग करता प्रतीत होता है , जो कि मैं नहीं चाहता था।

मैं मानता हूं कि एक वैकल्पिक डेटा संरचना बेहतर हो सकती है:

  • एक श्रेणी डेटाटाइप
  • डेटाफ्रेम (टपल का प्रत्येक तत्व एक स्तंभ बन जाता है)
  • स्ट्रिंग्स की एक श्रृंखला (केवल एक साथ टुपल्स को मिलाएं):

यह स्ट्रिंग्स की एक श्रृंखला बनाता है (यानी टपल को समाहित करके, एकल स्ट्रिंग में टपल में वर्णों को जोड़कर)

series_of_tuples.apply(''.join)

तो मैं तो श्रृंखला का उपयोग कर सकते हैंSeries.str.count

series_of_tuples.apply(''.join).str.count('H')==1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.