davis-stats 1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- davis_stats-1.0/PKG-INFO +21 -0
- davis_stats-1.0/davis_stats/__init__.py +6 -0
- davis_stats-1.0/davis_stats/data/__init__.py +18 -0
- davis_stats-1.0/davis_stats/data/ceo_comp.xlsx +0 -0
- davis_stats-1.0/davis_stats/stats/__init__.py +1 -0
- davis_stats-1.0/davis_stats/stats/reg.py +110 -0
- davis_stats-1.0/davis_stats/visualization/__init__.py +4 -0
- davis_stats-1.0/davis_stats/visualization/boxplot.py +34 -0
- davis_stats-1.0/davis_stats/visualization/histogram.py +71 -0
- davis_stats-1.0/davis_stats/visualization/scatter.py +132 -0
- davis_stats-1.0/davis_stats/visualization/trim.py +16 -0
- davis_stats-1.0/davis_stats.egg-info/PKG-INFO +21 -0
- davis_stats-1.0/davis_stats.egg-info/SOURCES.txt +16 -0
- davis_stats-1.0/davis_stats.egg-info/dependency_links.txt +1 -0
- davis_stats-1.0/davis_stats.egg-info/requires.txt +8 -0
- davis_stats-1.0/davis_stats.egg-info/top_level.txt +1 -0
- davis_stats-1.0/setup.cfg +4 -0
- davis_stats-1.0/setup.py +28 -0
davis_stats-1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: davis_stats
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: davis_stats is a teaching-focused repository
|
|
5
|
+
Author: Justin G. Davis
|
|
6
|
+
Author-email:
|
|
7
|
+
Keywords: statistics,data science,business analytics
|
|
8
|
+
Requires-Python: >=3.7
|
|
9
|
+
Requires-Dist: pandas>=1.0.0
|
|
10
|
+
Requires-Dist: openpyxl>=3.0.0
|
|
11
|
+
Requires-Dist: numpy>=1.20.0
|
|
12
|
+
Requires-Dist: matplotlib>=3.0.0
|
|
13
|
+
Requires-Dist: scipy>=1.6.0
|
|
14
|
+
Requires-Dist: seaborn>=0.12.0
|
|
15
|
+
Requires-Dist: statsmodels>=0.14.0
|
|
16
|
+
Requires-Dist: ipympl>=0.8.0
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: keywords
|
|
19
|
+
Dynamic: requires-dist
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
Dynamic: summary
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
DATA_DIR = Path(__file__).parent
|
|
5
|
+
|
|
6
|
+
class DataFrames:
|
|
7
|
+
_ceo_comp = None
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def ceo_comp(self):
|
|
11
|
+
if self._ceo_comp is None:
|
|
12
|
+
self._ceo_comp = pd.read_excel(DATA_DIR / 'ceo_comp.xlsx')
|
|
13
|
+
return self._ceo_comp
|
|
14
|
+
|
|
15
|
+
_data = DataFrames()
|
|
16
|
+
|
|
17
|
+
def ceo_comp():
|
|
18
|
+
return _data.ceo_comp
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .reg import reg
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
def reg(df, y, x, dummies=None, logistic=False):
|
|
2
|
+
"""
|
|
3
|
+
Run linear (OLS) or logistic regression.
|
|
4
|
+
|
|
5
|
+
Parameters
|
|
6
|
+
----------
|
|
7
|
+
df : pd.DataFrame
|
|
8
|
+
Input dataframe containing all variables
|
|
9
|
+
y : str
|
|
10
|
+
Name of the dependent variable column
|
|
11
|
+
x : str or list of str
|
|
12
|
+
Name(s) of independent variable column(s)
|
|
13
|
+
dummies : str or list of str, optional
|
|
14
|
+
Categorical variable(s) to convert to dummy variables
|
|
15
|
+
logistic : bool, default False
|
|
16
|
+
If True, run logistic regression; otherwise run OLS
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
statsmodels results object or None if fitting fails
|
|
21
|
+
"""
|
|
22
|
+
import statsmodels.api as sm
|
|
23
|
+
import pandas as pd
|
|
24
|
+
|
|
25
|
+
# Convert x to list if string, make copy to avoid modifying original
|
|
26
|
+
if isinstance(x, str):
|
|
27
|
+
x = [x]
|
|
28
|
+
else:
|
|
29
|
+
x = list(x)
|
|
30
|
+
|
|
31
|
+
df_reg = df.copy()
|
|
32
|
+
|
|
33
|
+
# Convert main variables to numeric
|
|
34
|
+
for col in [y] + x:
|
|
35
|
+
df_reg[col] = pd.to_numeric(df_reg[col], errors='coerce')
|
|
36
|
+
|
|
37
|
+
# Handle dummy variables
|
|
38
|
+
if dummies:
|
|
39
|
+
if isinstance(dummies, str):
|
|
40
|
+
dummies = [dummies]
|
|
41
|
+
|
|
42
|
+
for dummy_var in dummies:
|
|
43
|
+
# For logistic: filter to categories with variation in y
|
|
44
|
+
if logistic:
|
|
45
|
+
ct = pd.crosstab(df_reg[dummy_var], df_reg[y])
|
|
46
|
+
valid_categories = ct[(ct > 0).all(axis=1)].index
|
|
47
|
+
df_reg = df_reg[df_reg[dummy_var].isin(valid_categories)]
|
|
48
|
+
|
|
49
|
+
dummy_cols = pd.get_dummies(
|
|
50
|
+
df_reg[dummy_var],
|
|
51
|
+
prefix=dummy_var,
|
|
52
|
+
drop_first=True,
|
|
53
|
+
dtype=float
|
|
54
|
+
)
|
|
55
|
+
df_reg = pd.concat([df_reg, dummy_cols], axis=1)
|
|
56
|
+
x.extend(dummy_cols.columns.tolist())
|
|
57
|
+
|
|
58
|
+
# Drop rows with missing values
|
|
59
|
+
df_reg = df_reg.dropna(subset=[y] + x)
|
|
60
|
+
|
|
61
|
+
if len(df_reg) == 0:
|
|
62
|
+
print("Error: No observations remaining after dropping missing values")
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
# Prepare X and y
|
|
66
|
+
X = sm.add_constant(df_reg[x].astype(float))
|
|
67
|
+
y_data = df_reg[y].astype(float)
|
|
68
|
+
|
|
69
|
+
# Fit model
|
|
70
|
+
try:
|
|
71
|
+
if logistic:
|
|
72
|
+
model = sm.Logit(y_data, X)
|
|
73
|
+
results = model.fit(method='bfgs', maxiter=100, disp=0)
|
|
74
|
+
else:
|
|
75
|
+
model = sm.OLS(y_data, X)
|
|
76
|
+
results = model.fit()
|
|
77
|
+
|
|
78
|
+
print(results.summary())
|
|
79
|
+
return results
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(f"Error fitting model: {e}")
|
|
83
|
+
|
|
84
|
+
# For logistic with dummies, try again with larger categories only
|
|
85
|
+
if logistic and dummies:
|
|
86
|
+
min_obs = 30
|
|
87
|
+
print(f"\nRetrying with categories having at least {min_obs} observations...")
|
|
88
|
+
|
|
89
|
+
for dummy_var in dummies:
|
|
90
|
+
value_counts = df_reg[dummy_var].value_counts()
|
|
91
|
+
valid_categories = value_counts[value_counts >= min_obs].index
|
|
92
|
+
df_reg = df_reg[df_reg[dummy_var].isin(valid_categories)]
|
|
93
|
+
|
|
94
|
+
if len(df_reg) == 0:
|
|
95
|
+
print("Error: No observations remaining after filtering")
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
X = sm.add_constant(df_reg[x].astype(float))
|
|
100
|
+
y_data = df_reg[y].astype(float)
|
|
101
|
+
|
|
102
|
+
model = sm.Logit(y_data, X)
|
|
103
|
+
results = model.fit(method='bfgs', maxiter=100, disp=0)
|
|
104
|
+
print("\nResults with reduced sample:")
|
|
105
|
+
print(results.summary())
|
|
106
|
+
return results
|
|
107
|
+
except Exception as e2:
|
|
108
|
+
print(f"Error fitting reduced model: {e2}")
|
|
109
|
+
|
|
110
|
+
return None
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
from .trim import trim
|
|
4
|
+
|
|
5
|
+
def boxplot(series, title=None, trim_outliers=100, dpi=150, figsize=(6, 4)):
|
|
6
|
+
# Create figure and axis
|
|
7
|
+
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
|
|
8
|
+
|
|
9
|
+
if not title:
|
|
10
|
+
title = series.name
|
|
11
|
+
|
|
12
|
+
# Apply trimming if trim < 100
|
|
13
|
+
if trim_outliers < 100:
|
|
14
|
+
series = trim(series, trim_outliers)
|
|
15
|
+
title = f"{title} (outliers removed at {trim_outliers}% level)"
|
|
16
|
+
|
|
17
|
+
# Convert to numpy array and ensure 1D
|
|
18
|
+
data = np.array(series.dropna()).flatten()
|
|
19
|
+
|
|
20
|
+
# Create boxplot on the axis
|
|
21
|
+
ax.boxplot(data,
|
|
22
|
+
patch_artist=True,
|
|
23
|
+
boxprops=dict(facecolor='skyblue', color='black'),
|
|
24
|
+
medianprops=dict(color='black'),
|
|
25
|
+
flierprops=dict(marker='o', markerfacecolor='gray'),
|
|
26
|
+
whiskerprops=dict(color='black'),
|
|
27
|
+
capprops=dict(color='black'))
|
|
28
|
+
|
|
29
|
+
# Add labels and styling
|
|
30
|
+
ax.set_title(title)
|
|
31
|
+
ax.ticklabel_format(style='plain', axis='y')
|
|
32
|
+
ax.grid(True, linestyle='--', alpha=0.7)
|
|
33
|
+
|
|
34
|
+
plt.show(block=False)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from .trim import trim
|
|
5
|
+
|
|
6
|
+
def histogram(series, title=None, bins=30, trim_outliers=100, details=False, dpi=150, figsize=(6, 4)):
|
|
7
|
+
# Create figure and axis
|
|
8
|
+
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
|
|
9
|
+
|
|
10
|
+
# Get base title
|
|
11
|
+
if not title:
|
|
12
|
+
title = series.name
|
|
13
|
+
|
|
14
|
+
# Store original data for statistics BEFORE any trimming
|
|
15
|
+
original_data = np.array(series.dropna()).flatten()
|
|
16
|
+
|
|
17
|
+
# Apply trimming if trim < 100
|
|
18
|
+
if trim_outliers < 100:
|
|
19
|
+
series = trim(series, trim_outliers)
|
|
20
|
+
title = f"{title} (outliers removed at {trim_outliers}% level)"
|
|
21
|
+
|
|
22
|
+
# Convert to numpy array and handle NaN
|
|
23
|
+
data = np.array(series.dropna()).flatten()
|
|
24
|
+
|
|
25
|
+
# Create histogram
|
|
26
|
+
ax.hist(data,
|
|
27
|
+
bins=bins,
|
|
28
|
+
edgecolor='black',
|
|
29
|
+
color='skyblue',
|
|
30
|
+
alpha=0.7)
|
|
31
|
+
|
|
32
|
+
# Add labels and styling
|
|
33
|
+
ax.set_title(title)
|
|
34
|
+
ax.set_ylabel('Count')
|
|
35
|
+
ax.ticklabel_format(style='plain', axis='x')
|
|
36
|
+
ax.grid(True, linestyle='--', alpha=0.7)
|
|
37
|
+
|
|
38
|
+
if details:
|
|
39
|
+
# Add mean and median lines
|
|
40
|
+
mean = np.mean(original_data)
|
|
41
|
+
median = np.median(original_data)
|
|
42
|
+
ax.axvline(mean, color='red', linestyle='--', label=f'Mean: {mean:.2f}')
|
|
43
|
+
ax.axvline(median, color='green', linestyle='--', label=f'Median: {median:.2f}')
|
|
44
|
+
|
|
45
|
+
# Calculate standard deviations
|
|
46
|
+
std = np.std(original_data)
|
|
47
|
+
|
|
48
|
+
# Calculate percentages within SDs
|
|
49
|
+
within_1sd = np.sum((original_data >= mean - std) & (original_data <= mean + std)) / len(original_data) * 100
|
|
50
|
+
within_2sd = np.sum((original_data >= mean - 2*std) & (original_data <= mean + 2*std)) / len(original_data) * 100
|
|
51
|
+
within_3sd = np.sum((original_data >= mean - 3*std) & (original_data <= mean + 3*std)) / len(original_data) * 100
|
|
52
|
+
|
|
53
|
+
skew_val = pd.Series(original_data).skew()
|
|
54
|
+
|
|
55
|
+
# Add text box with statistics
|
|
56
|
+
stats_text = (
|
|
57
|
+
f'Skewness: {skew_val:.3f}\n'
|
|
58
|
+
f'Within 1 SD: {within_1sd:.1f}%\n'
|
|
59
|
+
f'Within 2 SD: {within_2sd:.1f}%\n'
|
|
60
|
+
f'Within 3 SD: {within_3sd:.1f}%'
|
|
61
|
+
)
|
|
62
|
+
plt.text(0.95, 0.95, stats_text,
|
|
63
|
+
transform=ax.transAxes,
|
|
64
|
+
verticalalignment='top',
|
|
65
|
+
horizontalalignment='right',
|
|
66
|
+
bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
|
|
67
|
+
|
|
68
|
+
# Add legend
|
|
69
|
+
plt.legend()
|
|
70
|
+
|
|
71
|
+
plt.show(block=False)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
def scatter(df, y, x, z=None, fit_line=False, dpi=150, figsize=(6, 4)):
|
|
2
|
+
"""
|
|
3
|
+
Create a nice scatter plot with optional fit line and correlation coefficient
|
|
4
|
+
|
|
5
|
+
Parameters:
|
|
6
|
+
df (pandas DataFrame): Input data
|
|
7
|
+
y (str): Column name for y-axis variable (vertical axis in 3D)
|
|
8
|
+
x (str): Column name for x-axis variable
|
|
9
|
+
z (str, optional): Column name for z-axis variable (creates 3D plot)
|
|
10
|
+
fit_line (bool): If True, adds best fit line (2D) or plane (3D)
|
|
11
|
+
dpi (int): Plot resolution
|
|
12
|
+
figsize (tuple): Figure size
|
|
13
|
+
"""
|
|
14
|
+
import seaborn as sns
|
|
15
|
+
import matplotlib.pyplot as plt
|
|
16
|
+
import numpy as np
|
|
17
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
18
|
+
|
|
19
|
+
# 2D scatter plot (original functionality)
|
|
20
|
+
if z is None:
|
|
21
|
+
# Calculate correlation coefficient
|
|
22
|
+
corr = df[x].corr(df[y])
|
|
23
|
+
|
|
24
|
+
# Set style
|
|
25
|
+
sns.set_style("whitegrid")
|
|
26
|
+
|
|
27
|
+
# Create figure
|
|
28
|
+
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
|
|
29
|
+
|
|
30
|
+
# Create scatter plot
|
|
31
|
+
if fit_line:
|
|
32
|
+
# Use seaborn's regplot for scatter + fit line
|
|
33
|
+
sns.regplot(data=df,
|
|
34
|
+
x=x,
|
|
35
|
+
y=y,
|
|
36
|
+
scatter_kws={'alpha':0.5},
|
|
37
|
+
line_kws={'color': 'red'},
|
|
38
|
+
ci=None)
|
|
39
|
+
else:
|
|
40
|
+
# Use seaborn's scatterplot
|
|
41
|
+
sns.scatterplot(data=df,
|
|
42
|
+
x=x,
|
|
43
|
+
y=y,
|
|
44
|
+
alpha=0.5)
|
|
45
|
+
|
|
46
|
+
# Customize plot - 2 variable title format
|
|
47
|
+
plt.title(f'{y} and {x}\nCorrelation: {corr:.3f}', pad=15)
|
|
48
|
+
plt.xlabel(x)
|
|
49
|
+
plt.ylabel(y)
|
|
50
|
+
|
|
51
|
+
# Adjust layout
|
|
52
|
+
plt.tight_layout()
|
|
53
|
+
|
|
54
|
+
# 3D scatter plot
|
|
55
|
+
else:
|
|
56
|
+
# Create 3D figure with larger size for better visibility
|
|
57
|
+
fig = plt.figure(figsize=figsize, dpi=dpi)
|
|
58
|
+
ax = fig.add_subplot(111, projection='3d')
|
|
59
|
+
|
|
60
|
+
# Remove NaN values for plotting
|
|
61
|
+
plot_df = df[[x, y, z]].dropna()
|
|
62
|
+
|
|
63
|
+
# Create 3D scatter plot with color spectrum and edge color
|
|
64
|
+
# In matplotlib 3D: (x-axis, y-axis, z-axis) where z-axis is VERTICAL
|
|
65
|
+
# So to make y variable vertical, it goes in the 3rd position
|
|
66
|
+
scatter = ax.scatter(plot_df[x], plot_df[z], plot_df[y],
|
|
67
|
+
c=plot_df[y], cmap='RdYlBu_r', s=50,
|
|
68
|
+
edgecolor='black', linewidth=0.5,
|
|
69
|
+
alpha=0.8)
|
|
70
|
+
|
|
71
|
+
# Add colorbar with more space
|
|
72
|
+
cbar = plt.colorbar(scatter, ax=ax, pad=0.15, shrink=0.8)
|
|
73
|
+
cbar.set_label(y, rotation=270, labelpad=15)
|
|
74
|
+
|
|
75
|
+
# Add best-fit plane if requested
|
|
76
|
+
if fit_line:
|
|
77
|
+
# Prepare data for plane fitting: y = a*x + b*z + c
|
|
78
|
+
X_data = np.column_stack([plot_df[x], plot_df[z], np.ones(len(plot_df))])
|
|
79
|
+
y_data = plot_df[y].values
|
|
80
|
+
|
|
81
|
+
# Fit plane using least squares: [a, b, c]
|
|
82
|
+
coeffs, residuals, rank, s = np.linalg.lstsq(X_data, y_data, rcond=None)
|
|
83
|
+
a, b, c = coeffs
|
|
84
|
+
|
|
85
|
+
# Create mesh grid for the regression plane
|
|
86
|
+
x_surf = np.linspace(plot_df[x].min(), plot_df[x].max(), 20)
|
|
87
|
+
z_surf = np.linspace(plot_df[z].min(), plot_df[z].max(), 20)
|
|
88
|
+
X_mesh, Z_mesh = np.meshgrid(x_surf, z_surf)
|
|
89
|
+
|
|
90
|
+
# Calculate y values for the plane
|
|
91
|
+
Y_mesh = a * X_mesh + b * Z_mesh + c
|
|
92
|
+
|
|
93
|
+
# Plot the regression plane with grid lines and semi-transparency
|
|
94
|
+
# Order: (x-axis, y-axis, z-axis) where z-axis is vertical
|
|
95
|
+
surf = ax.plot_surface(X_mesh, Z_mesh, Y_mesh,
|
|
96
|
+
alpha=0.4, cmap='coolwarm',
|
|
97
|
+
edgecolor='black', linewidth=0.5,
|
|
98
|
+
rstride=1, cstride=1,
|
|
99
|
+
antialiased=True)
|
|
100
|
+
|
|
101
|
+
# 3 variable title format
|
|
102
|
+
title = f'{y}, {x}, and {z}'
|
|
103
|
+
|
|
104
|
+
# Set axis labels
|
|
105
|
+
# In matplotlib 3D: x is horizontal left-right, y is horizontal front-back, z is VERTICAL
|
|
106
|
+
ax.set_xlabel(x, labelpad=10) # horizontal axis
|
|
107
|
+
ax.set_ylabel(z, labelpad=10) # horizontal axis (front-back)
|
|
108
|
+
ax.set_zlabel(y, labelpad=10) # VERTICAL axis (up-down)
|
|
109
|
+
|
|
110
|
+
# Move z-axis (vertical) ticks and label to the left to avoid colorbar overlap
|
|
111
|
+
ax.zaxis._axinfo['juggled'] = (1, 2, 0) # Move z-axis to left side
|
|
112
|
+
|
|
113
|
+
# Flip axes to go from least to greatest (normal order)
|
|
114
|
+
ax.invert_xaxis()
|
|
115
|
+
ax.invert_yaxis()
|
|
116
|
+
|
|
117
|
+
# Adjust the viewing angle for better perspective
|
|
118
|
+
ax.view_init(elev=25, azim=135)
|
|
119
|
+
|
|
120
|
+
# Make the grid lines more visible
|
|
121
|
+
ax.xaxis._axinfo["grid"]['color'] = (0.5, 0.5, 0.5, 0.5)
|
|
122
|
+
ax.yaxis._axinfo["grid"]['color'] = (0.5, 0.5, 0.5, 0.5)
|
|
123
|
+
ax.zaxis._axinfo["grid"]['color'] = (0.5, 0.5, 0.5, 0.5)
|
|
124
|
+
|
|
125
|
+
# Set title after everything else
|
|
126
|
+
ax.set_title(title, pad=15)
|
|
127
|
+
|
|
128
|
+
# Adjust layout
|
|
129
|
+
plt.tight_layout()
|
|
130
|
+
|
|
131
|
+
# Show plot
|
|
132
|
+
plt.show()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def trim(series, percentile_keep = 100):
|
|
4
|
+
# Calculate how much to remove
|
|
5
|
+
remove_pct = 100 - percentile_keep
|
|
6
|
+
|
|
7
|
+
# Find the threshold for most extreme values
|
|
8
|
+
# This gets the absolute distance from median for each point
|
|
9
|
+
median_val = np.median(series)
|
|
10
|
+
abs_deviations = np.abs(series - median_val)
|
|
11
|
+
|
|
12
|
+
# Find the threshold - keep values with smaller deviations
|
|
13
|
+
threshold = np.percentile(abs_deviations, percentile_keep)
|
|
14
|
+
|
|
15
|
+
# Return values within the threshold
|
|
16
|
+
return series[abs_deviations <= threshold]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: davis_stats
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: davis_stats is a teaching-focused repository
|
|
5
|
+
Author: Justin G. Davis
|
|
6
|
+
Author-email:
|
|
7
|
+
Keywords: statistics,data science,business analytics
|
|
8
|
+
Requires-Python: >=3.7
|
|
9
|
+
Requires-Dist: pandas>=1.0.0
|
|
10
|
+
Requires-Dist: openpyxl>=3.0.0
|
|
11
|
+
Requires-Dist: numpy>=1.20.0
|
|
12
|
+
Requires-Dist: matplotlib>=3.0.0
|
|
13
|
+
Requires-Dist: scipy>=1.6.0
|
|
14
|
+
Requires-Dist: seaborn>=0.12.0
|
|
15
|
+
Requires-Dist: statsmodels>=0.14.0
|
|
16
|
+
Requires-Dist: ipympl>=0.8.0
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: keywords
|
|
19
|
+
Dynamic: requires-dist
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
Dynamic: summary
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
davis_stats/__init__.py
|
|
3
|
+
davis_stats.egg-info/PKG-INFO
|
|
4
|
+
davis_stats.egg-info/SOURCES.txt
|
|
5
|
+
davis_stats.egg-info/dependency_links.txt
|
|
6
|
+
davis_stats.egg-info/requires.txt
|
|
7
|
+
davis_stats.egg-info/top_level.txt
|
|
8
|
+
davis_stats/data/__init__.py
|
|
9
|
+
davis_stats/data/ceo_comp.xlsx
|
|
10
|
+
davis_stats/stats/__init__.py
|
|
11
|
+
davis_stats/stats/reg.py
|
|
12
|
+
davis_stats/visualization/__init__.py
|
|
13
|
+
davis_stats/visualization/boxplot.py
|
|
14
|
+
davis_stats/visualization/histogram.py
|
|
15
|
+
davis_stats/visualization/scatter.py
|
|
16
|
+
davis_stats/visualization/trim.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
davis_stats
|
davis_stats-1.0/setup.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='davis_stats',
|
|
5
|
+
version='1.0',
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
package_data={
|
|
8
|
+
'davis_stats': ['data/*.xlsx']},
|
|
9
|
+
install_requires=[
|
|
10
|
+
'pandas>=1.0.0',
|
|
11
|
+
'openpyxl>=3.0.0',
|
|
12
|
+
'numpy>=1.20.0',
|
|
13
|
+
'matplotlib>=3.0.0',
|
|
14
|
+
'scipy>=1.6.0',
|
|
15
|
+
'seaborn>=0.12.0',
|
|
16
|
+
'statsmodels>=0.14.0',
|
|
17
|
+
'ipympl>=0.8.0'],
|
|
18
|
+
python_requires='>=3.7',
|
|
19
|
+
author='Justin G. Davis',
|
|
20
|
+
author_email='',
|
|
21
|
+
description='''
|
|
22
|
+
davis_stats is a teaching-focused repository
|
|
23
|
+
for applied statistics, data science, and
|
|
24
|
+
business analytics. It contains functions
|
|
25
|
+
and datasets to help W&L students develop
|
|
26
|
+
practical skills in data analysis, statistical
|
|
27
|
+
modeling, and real-world decision making.''',
|
|
28
|
+
keywords='statistics, data science, business analytics')
|