Completed
Push — master ( b0508b...8492fe )
by Mubdi
01:50
created

knowyourdata.kyd.KYD.display()   F

Complexity

Conditions 9

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 26
nop 2
dl 0
loc 39
rs 3
c 0
b 0
f 0
1
import numpy as np
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
import sys
0 ignored issues
show
introduced by
standard import "import sys" should be placed before "import numpy as np"
Loading history...
3
4
5
class KYD(object):
0 ignored issues
show
best-practice introduced by
Too many instance attributes (22/7)
Loading history...
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
6
    """The Central Class for KYD"""
7
8
    # Variable for Data Vector
9
    data = None
10
11
    # Initial Flags
12
    f_allfinite = False
13
    f_hasnan = False
14
    f_hasinf = False
15
16
    # Display Settings
17
    col_width = 10
18
    precision = 4
19
20
    def check_finite(self):
21
        """Checking to see if all elements are finite and setting flags"""
22
        if np.all(np.isfinite(self.data)):
23
            self.filt_data = self.data
24
            self.f_allfinite = True
25
        else:
26
            finite_inds = np.where(np.isfinite(self.data))
27
            self.filt_data = self.data[finite_inds]
28
29
            if np.any(np.isnan(self.data)):
30
                self.f_hasnan = True
31
            if np.any(np.isinf(self.data)):
32
                self.f_hasinf = True
33
34
    def check_struct(self):
35
        """Determining the Structure of the Numpy Array"""
36
        self.dtype = self.data.dtype
37
        self.ndim = self.data.ndim
38
        self.shape = self.data.shape
39
        self.size = self.data.size
40
        self.memsize = sys.getsizeof(self.data)
41
        self.human_memsize = sizeof_fmt(self.memsize)
42
43
    def get_basic_stats(self):
44
        """Get basic statistics about array"""
45
        self.min = np.min(self.filt_data)
46
        self.max = np.max(self.filt_data)
47
        self.range = self.max - self.min
48
        self.mean = np.mean(self.filt_data)
49
        self.std = np.std(self.filt_data)
50
        self.median = np.median(self.filt_data)
51
        self.firstquartile = np.percentile(self.filt_data, 25)
52
        self.thirdquartile = np.percentile(self.filt_data, 75)
53
        self.cl_99 = np.percentile(self.filt_data, np.array([0.5, 99.5]))
54
        self.cl_95 = np.percentile(self.filt_data, np.array([2.5, 97.5]))
55
        self.cl_68 = np.percentile(self.filt_data, np.array([16.0, 84.0]))
56
57
    def display_basic_stats(self):
58
        """Display basic statistics of array"""
59
        pstr_list = []
60
61
        pstr_struct_header1 = '\033[1m' + "Basic Statistics  " + '\033[0m'
62
63
        pstr_list.append(pstr_struct_header1)
64
65
        pstr_meanstdhead = (
66
            "\n"
67
            "{0:^15}"
68
            "{1:^15}"
69
        ).format("Mean", "Std Dev")
70
        pstr_meanstdhead = (
71
            "{0:^{self.col_width}}"
72
        ).format(pstr_meanstdhead, self=self)
73
        pstr_list.append(pstr_meanstdhead)
74
75
        pstr_meanstdstat = (
76
            "{self.mean:^15.{self.precision}}"
77
            "{self.std:^15.{self.precision}}"
78
        ).format(self=self)
79
        pstr_meanstdstat = (
80
            "{0:^{self.col_width}}"
81
        ).format(pstr_meanstdstat, self=self)
82
        pstr_list.append(pstr_meanstdstat)
83
84
        pstr_3pthead = (
85
            "\n"
86
            "{0:^10}"
87
            "{1:^10}"
88
            "{2:^10}"
89
            "{3:^10}"
90
            "{4:^10}"
91
        ).format('Min,', '1Q', 'Median', '3Q', 'Max')
92
        pstr_3pthead = (
93
            "{0:^{self.col_width}}"
94
        ).format(pstr_3pthead, self=self)
95
        pstr_list.append(pstr_3pthead)
96
97
        pstr_3ptstat = (
98
            "{self.min:^10.{self.precision}}"
99
            "{self.firstquartile:^10.{self.precision}}"
100
            "{self.median:^10.{self.precision}}"
101
            "{self.thirdquartile:^10.{self.precision}}"
102
            "{self.max:^10.{self.precision}}"
103
        ).format(self=self)
104
        pstr_3ptstat = (
105
            "{0:^{self.col_width}}"
106
        ).format(pstr_3ptstat, self=self)
107
        pstr_list.append(pstr_3ptstat)
108
109
        pstr_clhead = (
110
            "\n"
111
            "{0:^10}"
112
            "{1:^10}"
113
            "{2:^10}"
114
            "{3:^10}"
115
            "{4:^10}"
116
            "{5:^10}"
117
        ).format('-99 CL', '-95 CL', '-68 CL', '+68 CL', '+95 CL', '+99 CL')
118
        pstr_clhead = (
119
            "{0:^{self.col_width}}"
120
        ).format(pstr_clhead, self=self)
121
        pstr_list.append(pstr_clhead)
122
123
        pstr_clstat = (
124
            "{self.cl_99[0]:^10.{self.precision}}"
125
            "{self.cl_95[0]:^10.{self.precision}}"
126
            "{self.cl_68[0]:^10.{self.precision}}"
127
            "{self.cl_68[1]:^10.{self.precision}}"
128
            "{self.cl_95[1]:^10.{self.precision}}"
129
            "{self.cl_99[1]:^10.{self.precision}}"
130
        ).format(self=self)
131
        pstr_clstat = (
132
            "{0:^{self.col_width}}"
133
        ).format(pstr_clstat, self=self)
134
        pstr_list.append(pstr_clstat)
135
136
        return pstr_list
137
138
    def display_struct(self):
139
        """Display information about array structure"""
140
141
        pstr_list = []
142
143
        # pstr_struct_header0 = "................."
144
        pstr_struct_header1 = '\033[1m' + "Array Structure  " + '\033[0m'
145
        pstr_struct_header2 = "                 "
146
147
        # pstr_list.append(pstr_struct_header0)
148
        pstr_list.append(pstr_struct_header1)
149
        pstr_list.append(pstr_struct_header2)
150
151
        pstr_n_dim = (
152
            "Number of Dimensions:"
153
            "{self.ndim:>15}").format(
154
                self=self)
155
        pstr_list.append(pstr_n_dim)
156
157
        pstr_shape = (
158
            "Shape of Dimensions: "
159
            "{self.shape!s:>15}").format(
160
                self=self)
161
        pstr_list.append(pstr_shape)
162
163
        pstr_dtype = (
164
            "Array Data Type:     "
165
            "{self.dtype!s:>15}").format(
166
                self=self)
167
        pstr_list.append(pstr_dtype)
168
169
        pstr_memsize = (
170
            "Memory Size: "
171
            "{self.human_memsize:>15}").format(
172
                self=self)
173
        pstr_list.append(pstr_memsize)
174
175
        return pstr_list
176
177
    def display(self, short=False):
178
        """Displaying all relevant statistics"""
179
180
        if short:
181
            pass
182
183
        print()
184
        pstr_basic = self.display_basic_stats()
185
        pstr_struct = self.display_struct()
186
187
        l_colwidth = 0
188
        for string1 in pstr_basic:
189
            if len(string1) > l_colwidth:
190
                l_colwidth = len(string1)
191
        l_colwidth += 1
192
193
        r_colwidth = 0
194
        for string1 in pstr_basic:
195
            if len(string1) > r_colwidth:
196
                r_colwidth = len(string1)
197
198
        # new_colwidth = self.col_width + 20
199
200
        # Finding the longest string
201
        len_list = max([len(pstr_basic), len(pstr_struct)])
202
203
        for i in range(len_list):
204
            tmp_str = ''
205
            if i < len(pstr_basic):
206
                tmp_str += (pstr_basic[i].ljust(l_colwidth))
207
            else:
208
                tmp_str += ''.ljust(l_colwidth)
209
            tmp_str += ' | '
210
            if i < len(pstr_struct):
211
                tmp_str += (pstr_struct[i]).ljust(r_colwidth)
212
213
            print(tmp_str)
214
215
        print()
216
217
    def __init__(self, data):
218
        super(KYD, self).__init__()
219
220
        # Ensuring that the array is a numpy array
221
        if type(data) != np.ndarray:
0 ignored issues
show
introduced by
Using type() instead of isinstance() for a typecheck.
Loading history...
222
            data = np.array(data)
223
224
        self.data = data
225
226
        self.check_finite()
227
        self.check_struct()
228
        self.get_basic_stats()
229
230
231
def sizeof_fmt(num, suffix='B'):
232
    """Return human readable version of in-memory size.
233
    Code from Fred Cirera from Stack Overflow:
234
    https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
235
    """
236
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
237
        if abs(num) < 1024.0:
238
            return "%3.1f%s%s" % (num, unit, suffix)
239
        num /= 1024.0
240
    return "%.1f%s%s" % (num, 'Yi', suffix)
241
242
243
def kyd(data, full_statistics=False):
244
    """Print statistics of any numpy array
245
246
    Keyword arguments:
247
    full_statistics -- printing all detailed statistics of the sources
248
249
    """
250
251
    data_kyd = KYD(data)
252
    if full_statistics:
253
        data_kyd.display()
254
    else:
255
        data_kyd.display(short=True)
256
257
    return data_kyd
258