स्काइप / सुन्न के साथ अजगर में बायनिंग डेटा


108

वहाँ एक और अधिक कुशल तरीका है कि पूर्व निर्धारित डिब्बे में एक सरणी के एक औसत लेने के लिए? उदाहरण के लिए, मेरे पास संख्याओं की एक सरणी है और उस सरणी में बिन शुरू और अंत पदों के अनुरूप एक सरणी है, और मैं बस उन बिन में मतलब लेना चाहता हूं? मेरे पास कोड है जो इसे नीचे करता है लेकिन मैं सोच रहा हूं कि इसे कैसे काटा जा सकता है और इसमें सुधार किया जा सकता है। धन्यवाद।

from scipy import *
from numpy import *

def get_bin_mean(a, b_start, b_end):
    ind_upper = nonzero(a >= b_start)[0]
    a_upper = a[ind_upper]
    a_range = a_upper[nonzero(a_upper < b_end)[0]]
    mean_val = mean(a_range)
    return mean_val


data = rand(100)
bins = linspace(0, 1, 10)
binned_data = []

n = 0
for n in range(0, len(bins)-1):
    b_start = bins[n]
    b_end = bins[n+1]
    binned_data.append(get_bin_mean(data, b_start, b_end))

print binned_data

जवाबों:


181

यह संभवतः अधिक तेज़ और उपयोग में आसान है numpy.digitize():

import numpy
data = numpy.random.random(100)
bins = numpy.linspace(0, 1, 10)
digitized = numpy.digitize(data, bins)
bin_means = [data[digitized == i].mean() for i in range(1, len(bins))]

इसका उपयोग करने के लिए एक विकल्प है numpy.histogram():

bin_means = (numpy.histogram(data, bins, weights=data)[0] /
             numpy.histogram(data, bins)[0])

अपने लिए प्रयास करें कि कौन सा तेज है ... :)


1
मुझे कोई अंतर दिखाई नहीं देता - जो तेज है?

4
@user: मुझे नहीं पता कि कौन सा आपके डेटा और मापदंडों के लिए तेज़ है। दोनों विधियां आपकी तुलना में तेज़ होनी चाहिए, और मुझे उम्मीद है कि histogram()बड़ी संख्या में डिब्बे के लिए विधि तेज़ होगी। लेकिन आपको खुद को प्रोफाइल बनाना होगा, मैं आपके लिए ऐसा नहीं कर सकता।
स्वेन मार्नाच

39

स्किपी (> = 0.11) फ़ंक्शन scipy.stats.binned_statistic है विशेष रूप से उपरोक्त प्रश्न को संबोधित करता है।

पिछले उत्तरों के समान उदाहरण के लिए, स्किपी समाधान होगा

import numpy as np
from scipy.stats import binned_statistic

data = np.random.rand(100)
bin_means = binned_statistic(data, data, bins=10, range=(0, 1))[0]

16

निश्चित नहीं है कि इस धागे को नेक्रोड क्यों मिला; लेकिन यहां एक 2014 का स्वीकृत जवाब है, जो और भी तेज होना चाहिए:

import numpy as np

data = np.random.rand(100)
bins = 10
slices = np.linspace(0, 100, bins+1, True).astype(np.int)
counts = np.diff(slices)

mean = np.add.reduceat(data, slices[:-1]) / counts
print mean

3
आप एक अलग सवाल का जवाब दे रहे हैं। उदाहरण के लिए आपका mean[0] = np.mean(data[0:10]), जबकि सही उत्तर होना चाहिएnp.mean(data[data < 10])
रग्गेरो तुर्रा

5

Numpy_indexed पैकेज (अस्वीकरण: मैं उसके लेखक हूँ) कार्यक्षमता कुशलता से इस प्रकार की कार्रवाई करने में शामिल हैं:

import numpy_indexed as npi
print(npi.group_by(np.digitize(data, bins)).mean(data))

यह अनिवार्य रूप से वही समाधान है जो मैंने पहले पोस्ट किया था; लेकिन अब परीक्षण और सभी के साथ एक अच्छा इंटरफ़ेस में लिपटे :)


3

मैं जोड़ूंगा, और इस सवाल का जवाब देने के लिए कि हिस्टोग्राम 2 डी पायथन का उपयोग करने वाले बिन मूल्यों को खोजने के लिए भी कि स्कैपी में एक फ़ंक्शन है जो विशेष रूप से एक या अधिक डेटा के सेट के लिए एक द्वि-आयामी द्वैध सांख्यिकी की गणना करने के लिए डिज़ाइन किया गया है।

import numpy as np
from scipy.stats import binned_statistic_2d

x = np.random.rand(100)
y = np.random.rand(100)
values = np.random.rand(100)
bin_means = binned_statistic_2d(x, y, values, bins=10).statistic

फ़ंक्शन scipy.stats.binned_statistic_dd उच्च आयाम डेटासेट के लिए इस कवक का सामान्यीकरण है


1

एक अन्य विकल्प ufunc.at का उपयोग करना है। यह विधि निर्दिष्ट सूचकांकों पर एक वांछित संचालन को लागू करती है। हम खोज विधि का उपयोग करके प्रत्येक डेटा पॉइंट के लिए बिन स्थिति प्राप्त कर सकते हैं। फिर हम बिन_इंडेक्स द्वारा दिए गए इंडेक्स में हिस्टोग्राम की स्थिति के अनुसार 1 की वृद्धि पर उपयोग कर सकते हैं, हर बार जब हम बिन_इंडेक्स पर एक सूचकांक का सामना करते हैं।

np.random.seed(1)
data = np.random.random(100) * 100
bins = np.linspace(0, 100, 10)

histogram = np.zeros_like(bins)

bin_indexes = np.searchsorted(bins, data)
np.add.at(histogram, bin_indexes, 1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.