1.0 Measuring the Link Between Figure 8 Knots and Ascher Sum Summand Ranges
We are now equipped with two dataframes:
A Sums-and-Eight-Knots Dataframe showing Sum Information for pendant ascher sums, augmented with information about figure-eight-knot cords in the summand ranges.
```{python}import osimport numpy as npfrom scipy import statsimport pandas as pdfrom pandas import Series, DataFramefrom collections import Counterimport qollqa_chuspa as qc # A Khipu Maker is known (in Quechua) as a Khipu Kamayuqimport utils_loom as uloomimport utils_khipu as ukhipuimport utils_pandas as upandaimport utils_kfg_locations as uloc# Plotlyimport plotlyfrom plotly.offline import iplot, init_notebook_modeimport plotly.graph_objects as goimport plotly.express as pximport plotly.figure_factory as ffplotly.offline.init_notebook_mode(connected = False)# Load all khipus(khipu_dict, all_khipus) = qc.fetch_khipus()```
1.1 Examining the Distribution of Figure-8-Knots vs Pendant Ascher Sums
First let’s look at two distributions:
A Khipu’s Pendant Ascher sums vs # Khipu’sFigure8 Knot Cords
A Khipu’s Pendant Ascher sums vs # Khipu’s Pendant Ascher Sums marked by Figure8 Knot Cords
As seen below the first distribution show’s a fairly wide standard deviation. However the second distribution brings the relation into a little more focus:
Code
```{python}pendant_ascher_sums_df = pd.read_csv(f"{uloc.fieldmarks_data_dir()}/figure8knotsums.csv")left_handed_eightknotsums_df = pd.read_csv(f"{uloc.fieldmarks_data_dir()}/left_handed_sums_8knot_types.csv")right_handed_eightknotsums_df = pd.read_csv(f"{uloc.fieldmarks_data_dir()}/right_handed_sums_8knot_types.csv")all_eightknotsums_df = pd.read_csv(f"{uloc.fieldmarks_data_dir()}/all_sums_8knot_types.csv")all_eightknotsums_df['num_total_cords'] = [khipu_dict[kfg_name].num_all_cords(include_subsidiaries=True) for kfg_name in all_eightknotsums_df['kfg_name'].to_list()]all_eightknotsums_df['num_pendant_cords'] = [khipu_dict[kfg_name].num_pendant_cords() for kfg_name in all_eightknotsums_df['kfg_name'].to_list()]```
Code
```{python}fig = (px.scatter(all_eightknotsums_df, x='num_ascher_sums', y='total_8knot_cords', color='num_pendant_cords', color_continuous_scale='Bluered_r', log_x=True, log_y=True, title="By Khipu - # All Pendant Sum Cords vs # All Figure8Knot Cords - Hover over Dot for Detail", labels={'num_ascher_sums':'# Basic Ascher Sums (Log scale)', 'total_8knot_cords':'# Total Figure-8-Knot Cords (Log scale)', 'num_pendant_cords': '# Pendant Cords' }, width=944, height=944, trendline="ols", hover_data=['kfg_name', 'num_ascher_sums', 'total_sum8knots', 'num_pendant_cords'])).show()```
Code
```{python}fig = (px.scatter(all_eightknotsums_df, x='num_ascher_sums', y='total_sum8knots', color='num_pendant_cords', color_continuous_scale='Bluered_r', log_x=True, log_y=True, title="By Khipu - # All Pendant Sum Cords vs # Figure-8-Knot Sum Marker Cords - Hover over Dot for Detail", labels={'num_ascher_sums':'# Basic Ascher Sums (Log scale)', 'total_sum8knots':'# Basic Ascher Sums with Figure 8 Knot Indicator (Log scale)', 'num_pendant_cords': '# Pendant Cords' }, width=944, height=944, trendline="ols", hover_data=['kfg_name', 'num_ascher_sums', 'total_sum8knots', 'num_pendant_cords'])).show()```
1.2 Examining the Figure-8-Knot Cords over Summand Ranges
Similar to the Group/Cluster analysis that we did on Figure8Knot Cord Locations, we can compute Normalized Cord Locations for Figure-8-Knot Cords over Summand Ranges. In groups, the cords are contiguous. While this also true for pendant-pendant-sum summand ranges, it is not true for indexed-pendant-sums (ie. sum=p12+p22+p32+…) or colored-pendant-sums. Consequently, to generalize for normalized cord locations, we will use the index of the cord in its summand cords as our measurement metric, rather than the actual pendant index.
```{python}# Build a dictionary of khipu names, with associated summands (as list of (list of cords))pendant_ascher_sums_kfg_names = ukhipu.lexigraphic_order(uloom.unique(pendant_ascher_sums_df['kfg_name'].to_list()))summand_cord_dict = {kfg_name:[] for kfg_name in pendant_ascher_sums_kfg_names}summand_8knot_cords = []# Play with this number to reduce the influence of sums with only a few summands# For example 5 still causes spikes at the end, but flattens the middle# bandwith_limit_min = 2 # Default minimumfor _,sum_row in pendant_ascher_sums_df.iterrows(): kfg_name = sum_row['kfg_name'] the_khipu = khipu_dict[kfg_name] summand_cords = the_khipu.cords_from_sum_string(sum_row['summand_string'], one_based=False) # if len(summand_cords) <= bandwith_limit_min: # continue summand_cord_dict[kfg_name].append(summand_cords) for aCord in summand_cords: num_summands = len(summand_cords) the_leading_position = leading_position(aCord, summand_cords) the_trailing_position = trailing_position(aCord, summand_cords) cord_dict = {'kfg_name':kfg_name, 'sum_cord':sum_row['cord_name'], 'summand_cords': ",".join([cord.pendant_name for cord in summand_cords]), 'num_summands':num_summands, 'cord_name':aCord.pendant_name, 'is_subsidiary':aCord.has_eight_knot(include_pendant=False,include_subsidiaries=True), 'cord':aCord, 'leading_position': leading_position(aCord, summand_cords), 'trailing_position': trailing_position(aCord, summand_cords), 'in_left_half': in_left_half(the_leading_position, num_summands, include_middle=False), 'in_right_half': in_right_half(the_trailing_position, num_summands, include_middle=False), 'normalized_position': float(summand_cords.index(aCord))/float(num_summands-1) } if aCord.has_eight_knot(include_pendants=True,include_subsidiaries=True): summand_8knot_cords.append(cord_dict)```
Code
```{python}leading_figure_8_knot_cord_in_summand_ranges = [aCordDict['leading_position'] for aCordDict in summand_8knot_cords if aCordDict['in_left_half']] fig = (px.histogram(leading_figure_8_knot_cord_in_summand_ranges, nbins=160, width=944, height=500, title='Histogram of Left-Half Summand Range 8-Knot Cord Locations by LEADING Position from Left', labels={'value':'Locations by LEADING Cord Position (from Left) in a Summand Range'}, ) .update_layout( showlegend=False, font_family="Lucida Grande", font_color="black", font_size=12, title_font_family="Lucida Grande", title_font_color="black", legend_title_font_color="black") .show()) ```
Code
```{python}trailing_figure_8_knot_cord_in_summand_ranges = [aCordDict['trailing_position'] for aCordDict in summand_8knot_cords if aCordDict['in_right_half']] fig = (px.histogram(trailing_figure_8_knot_cord_in_summand_ranges, nbins=160, width=944, height=500, title='Histogram of Right-Half Summand Range 8-Knot Cord Locations by Trailing Position from Right', labels={'value':'Locations by Trailing Cord Position (from Right) in a Summand Range'}, ) .update_layout( showlegend=False, font_family="Lucida Grande", font_color="black", font_size=12, title_font_family="Lucida Grande", title_font_color="black", legend_title_font_color="black") .show())```
Code
```{python}normalized_8knot_cord_in_summand_locs = [aCordDict['normalized_position'] for aCordDict in summand_8knot_cords if (aCordDict['in_left_half'] or aCordDict['in_right_half'])] fig = (px.histogram(normalized_8knot_cord_in_summand_locs, nbins=100, width=944, height=500, title='Histogram of Figure-8-Knot Normalized Cord Locations by Cord over a Summand Range') .update_layout( showlegend=False, font_family="Lucida Grande", font_color="black", font_size=12, title_font_family="Lucida Grande", title_font_color="black", legend_title_font_color="black") .show())```
The spikes in the middle, at .333, .2, etc are the “harmonic” 1/n counts caused by 3 cord sequences, 4 cord sequences, etc., where the middle cord has an 8-knot (or its subsidiary), or the 2nd of 4 cords, etc..
2.0 Correlation
As a first step, let’s use the contigency table we built to evaluate which marks are most typical to identify summand ranges in an Ascher sum.
2.2.1 Totals Correlation Matrix for Right-Handed 8Knot Sums
Markers
# Ascher Sums
# Pps Sums
# Cps Sums
# Ips Sums
Total 8Knot Cords
Total Sum8Knots
Total Sole8Knots
Total Trailing8Knots
Total Exact Sole8Knots
Total Exact Trailing8Knots
Total Close Sole8Knots
Total Close Trailing8Knots
0
# Ascher Sums
1
0.939332
0.800366
0.713307
0.573015
0.664177
0.509671
0.621999
0.532267
0.632791
0.507827
0.568578
1
# Pps Sums
0.939332
1
0.655455
0.598529
0.53477
0.620943
0.477433
0.605176
0.500382
0.610611
0.47216
0.561434
2
# Cps Sums
0.800366
0.655455
1
0.527032
0.549278
0.59831
0.475298
0.536619
0.493177
0.539519
0.472877
0.491748
3
# Ips Sums
0.713307
0.598529
0.527032
1
0.436404
0.492266
0.355097
0.495715
0.366676
0.503991
0.369016
0.447228
4
Total 8Knot Cords
0.573015
0.53477
0.549278
0.436404
1
0.880645
0.763182
0.637174
0.760499
0.624552
0.727233
0.574227
5
Total Sum8Knots
0.664177
0.620943
0.59831
0.492266
0.880645
1
0.875236
0.65349
0.846803
0.685631
0.854764
0.551337
6
Total Sole8Knots
0.509671
0.477433
0.475298
0.355097
0.763182
0.875236
1
0.372837
0.968696
0.373629
0.943621
0.332265
7
Total Trailing8Knots
0.621999
0.605176
0.536619
0.495715
0.637174
0.65349
0.372837
1
0.38226
0.912383
0.375496
0.904691
8
Total Exact Sole8Knots
0.532267
0.500382
0.493177
0.366676
0.760499
0.846803
0.968696
0.38226
1
0.39136
0.867862
0.338447
9
Total Exact Trailing8Knots
0.632791
0.610611
0.539519
0.503991
0.624552
0.685631
0.373629
0.912383
0.39136
1
0.377167
0.727431
10
Total Close Sole8Knots
0.507827
0.47216
0.472877
0.369016
0.727233
0.854764
0.943621
0.375496
0.867862
0.377167
1
0.328479
11
Total Close Trailing8Knots
0.568578
0.561434
0.491748
0.447228
0.574227
0.551337
0.332265
0.904691
0.338447
0.727431
0.328479
1
2.2.2 Details Correlation Matrix for Right-Handed 8Knot Sums
Markers
# Ascher Sums
# Pps Sums
# Cps Sums
# Ips Sums
Left Exact Pendant 8Knot Cord Type Sole8Knot
Left Exact Pendant 8Knot Cord Type Trailing8Knot
Right Exact Pendant 8Knot Cord Type Sole8Knot
Right Exact Pendant 8Knot Cord Type Trailing8Knot
Left Exact Subsidiary 8Knot Cord Type Sole8Knot
Left Exact Subsidiary 8Knot Cord Type Trailing8Knot
Right Exact Subsidiary 8Knot Cord Type Sole8Knot
Right Exact Subsidiary 8Knot Cord Type Trailing8Knot
Left Close Pendant 8Knot Cord Type Sole8Knot
Left Close Pendant 8Knot Cord Type Trailing8Knot
Right Close Pendant 8Knot Cord Type Sole8Knot
Right Close Pendant 8Knot Cord Type Trailing8Knot
Left Close Subsidiary 8Knot Cord Type Sole8Knot
Left Close Subsidiary 8Knot Cord Type Trailing8Knot
Right Close Subsidiary 8Knot Cord Type Sole8Knot
Right Close Subsidiary 8Knot Cord Type Trailing8Knot
0
# Ascher Sums
1
0.939332
0.800366
0.713307
0.399687
0.604616
0.44337
0.591881
0.372098
0.236934
0.397923
0.272567
0.387249
0.539967
0.395177
0.523485
0.398641
0.306553
0.408651
0.235105
1
# Pps Sums
0.939332
1
0.655455
0.598529
0.402435
0.583419
0.422585
0.586111
0.329716
0.229645
0.355146
0.263212
0.375652
0.533139
0.361325
0.524896
0.386428
0.286542
0.359598
0.219833
2
# Cps Sums
0.800366
0.655455
1
0.527032
0.37661
0.522281
0.423763
0.510917
0.356355
0.197998
0.395577
0.240902
0.380441
0.47233
0.405324
0.445796
0.364102
0.275713
0.413595
0.220166
3
# Ips Sums
0.713307
0.598529
0.527032
1
0.249146
0.490033
0.337277
0.462593
0.309
0.218203
0.279618
0.195836
0.300178
0.394717
0.289449
0.42989
0.288791
0.260018
0.312279
0.195163
12
Left Exact Pendant 8Knot Cord Type Sole8Knot
0.399687
0.402435
0.37661
0.249146
1
0.178685
0.648193
0.209645
0.283104
0.0124537
0.337608
-0.0148578
0.738293
0.195852
0.610128
0.15968
0.370028
0.012975
0.314333
0.0148751
13
Left Exact Pendant 8Knot Cord Type Trailing8Knot
0.604616
0.583419
0.522281
0.490033
0.178685
1
0.271785
0.697343
0.287746
0.228418
0.283734
0.312874
0.216206
0.668737
0.210201
0.577349
0.287554
0.328771
0.275379
0.277126
14
Right Exact Pendant 8Knot Cord Type Sole8Knot
0.44337
0.422585
0.423763
0.337277
0.648193
0.271785
1
0.271077
0.365724
0.0592264
0.381023
0.0505534
0.679436
0.240034
0.715463
0.191983
0.430866
0.135784
0.396913
0.082391
15
Right Exact Pendant 8Knot Cord Type Trailing8Knot
0.591881
0.586111
0.510917
0.462593
0.209645
0.697343
0.271077
1
0.317658
0.24441
0.302013
0.357137
0.232217
0.602267
0.181283
0.638875
0.314117
0.379622
0.325728
0.308684
16
Left Exact Subsidiary 8Knot Cord Type Sole8Knot
0.372098
0.329716
0.356355
0.309
0.283104
0.287746
0.365724
0.317658
1
0.310723
0.712757
0.269956
0.314619
0.253967
0.361568
0.190594
0.692194
0.304425
0.702125
0.285374
17
Left Exact Subsidiary 8Knot Cord Type Trailing8Knot
0.236934
0.229645
0.197998
0.218203
0.0124537
0.228418
0.0592264
0.24441
0.310723
1
0.303167
0.664067
-0.0186791
0.259496
0.00223261
0.248021
0.308222
0.588608
0.276163
0.583068
18
Right Exact Subsidiary 8Knot Cord Type Sole8Knot
0.397923
0.355146
0.395577
0.279618
0.337608
0.283734
0.381023
0.302013
0.712757
0.303167
1
0.257631
0.36188
0.265124
0.372944
0.249857
0.698246
0.296793
0.714776
0.20677
19
Right Exact Subsidiary 8Knot Cord Type Trailing8Knot
0.272567
0.263212
0.240902
0.195836
-0.0148578
0.312874
0.0505534
0.357137
0.269956
0.664067
0.257631
1
0.0312377
0.322955
0.0425252
0.33746
0.252457
0.685554
0.260263
0.694134
20
Left Close Pendant 8Knot Cord Type Sole8Knot
0.387249
0.375652
0.380441
0.300178
0.738293
0.216206
0.679436
0.232217
0.314619
-0.0186791
0.36188
0.0312377
1
0.149124
0.643274
0.156699
0.341948
0.034155
0.329152
0.0292368
21
Left Close Pendant 8Knot Cord Type Trailing8Knot
0.539967
0.533139
0.47233
0.394717
0.195852
0.668737
0.240034
0.602267
0.253967
0.259496
0.265124
0.322955
0.149124
1
0.192524
0.589833
0.238974
0.350788
0.309794
0.263385
22
Right Close Pendant 8Knot Cord Type Sole8Knot
0.395177
0.361325
0.405324
0.289449
0.610128
0.210201
0.715463
0.181283
0.361568
0.00223261
0.372944
0.0425252
0.643274
0.192524
1
0.132001
0.362932
0.0687638
0.372978
0.0527134
23
Right Close Pendant 8Knot Cord Type Trailing8Knot
0.523485
0.524896
0.445796
0.42989
0.15968
0.577349
0.191983
0.638875
0.190594
0.248021
0.249857
0.33746
0.156699
0.589833
0.132001
1
0.238546
0.361342
0.311055
0.261411
24
Left Close Subsidiary 8Knot Cord Type Sole8Knot
0.398641
0.386428
0.364102
0.288791
0.370028
0.287554
0.430866
0.314117
0.692194
0.308222
0.698246
0.252457
0.341948
0.238974
0.362932
0.238546
1
0.322512
0.734032
0.273338
25
Left Close Subsidiary 8Knot Cord Type Trailing8Knot
0.306553
0.286542
0.275713
0.260018
0.012975
0.328771
0.135784
0.379622
0.304425
0.588608
0.296793
0.685554
0.034155
0.350788
0.0687638
0.361342
0.322512
1
0.292727
0.715569
26
Right Close Subsidiary 8Knot Cord Type Sole8Knot
0.408651
0.359598
0.413595
0.312279
0.314333
0.275379
0.396913
0.325728
0.702125
0.276163
0.714776
0.260263
0.329152
0.309794
0.372978
0.311055
0.734032
0.292727
1
0.249226
27
Right Close Subsidiary 8Knot Cord Type Trailing8Knot
0.235105
0.219833
0.220166
0.195163
0.0148751
0.277126
0.082391
0.308684
0.285374
0.583068
0.20677
0.694134
0.0292368
0.263385
0.0527134
0.261411
0.273338
0.715569
0.249226
1
3.0 Chi-squared test between Basic Ascher Sums and Figure 8 Knot Cords
Code
```{python}from scipy.stats import chi2_contingencydef perform_chi_squared_8knot_test(df): chi_sq_input_df = df[['num_ascher_sums', 'total_sum8knots', 'total_sole8knots', 'total_trailing8knots']] chi_sq_input_df = chi_sq_input_df[chi_sq_input_df['num_ascher_sums'] > 0] # Perform chi-squared test chi2, p, dof, expected = chi2_contingency(chi_sq_input_df) # Print the results print(f"p-value: {p:e}") return chi_sq_input_dfprint("\nChi-squared p values for Left-Handed 8Knot Sums")print( "================================================")left_chi_sq_df = perform_chi_squared_8knot_test(left_handed_eightknotsums_df)print("\nChi-squared p values for Right-Handed 8Knot Sums")print( "=================================================")right_chi_sq_df = perform_chi_squared_8knot_test(right_handed_eightknotsums_df)```
Chi-squared p values for Left-Handed 8Knot Sums
================================================
p-value: 0.000000e+00
Chi-squared p values for Right-Handed 8Knot Sums
=================================================
p-value: 0.000000e+00
4.0 Angle Between Pendant Ascher Sums vs. Figure-8-Knot Markers
What is the vector angle between pendant Ascher sums, and the various figure-eight-knot markers (i.e. how closely do they match?)
Code
```{python}print(f"Angle between num_pendant_ascher_sums and:")for i in range(2, len(all_eightknotsums_df.columns)): print(f"\t{all_eightknotsums_df.columns[i]}: {uloom.degrees_between(all_eightknotsums_df['num_ascher_sums'].to_list(), all_eightknotsums_df[all_eightknotsums_df.columns[i]].to_list()):.1f}°")```
5.0 Figure-8-Knot Cords Marking Sums vs Sums Marked by Figure-8-Knot Cords.
There is a difference between:
The number of 8 knot cords that mark an ascher sum and
The number of ascher sums marked by an eight knot cord
The reason is that we allow ascher sums to be marked by neighboring cords, as well as the left and right edges of the summand range. Consequently one cord can serve as a left-edge summand marker, and a close right-edge of a previous summand range. A similar duplicity exists for right/left summand ranges. For example, in KH0696, pendant p24 marks an exact sum relationship with p38, and a left close relationship with sum cord p35. In the figure8 knot dataframe we mark this as figure8knot p24 matches with p38, and leave it at that, ignoring p35. But in the Ascher sum dataframe we record both.
Code
```{python}aDF=pendant_ascher_sums_df khipu_df = aDF[aDF['kfg_name']=='AK001'].fillna('')khipu_df = khipu_df[khipu_df['has_figure8knot_indicator']==True]print("Sums with a Figure 8 Knot Indicator for AK001")khipu_df.head(10)```
Sums with a Figure 8 Knot Indicator for AK001
kfg_name
cord_name
cord_index
cord_value
cord_color
num_summands
handedness
has_figure8knot_indicator
has_left_exact_8knot_cord
has_right_exact_8knot_cord
...
summand_string
sum_type
left_exact_pendant_8knot_cord_type
right_exact_pendant_8knot_cord_type
left_exact_subsidiary_8knot_cord_type
right_exact_subsidiary_8knot_cord_type
left_close_pendant_8knot_cord_type
right_close_pendant_8knot_cord_type
left_close_subsidiary_8knot_cord_type
right_close_subsidiary_8knot_cord_type
0
AK001
p24
[2, 0]
11
W
3
-2
True
False
False
...
W:YB:G@[1, 5]:4 + AB@[1, 6]:4 + AB@[1, 7]:3
pendant_pendant_sum
trailing_8knot
1
AK001
p33
[4, 0]
68
W
14
-8
True
True
False
...
W:YB:G@[1, 2]:1 + W:YB:G@[1, 3]:9 + W:YB:G@[1,...
pendant_pendant_sum
sole_8knot
3
AK001
p35
[4, 2]
33
YB
7
-7
True
False
False
...
W@[2, 1]:9 + W@[2, 2]:7 + W@[2, 3]:2 + W@[2, 4...
pendant_pendant_sum
trailing_8knot
4
AK001
p37
[4, 4]
27
W:YB:G
3
-12
True
True
False
...
W@[2, 0]:11 + W@[2, 1]:9 + W@[2, 2]:7
pendant_pendant_sum
trailing_8knot
5
AK001
p38
[4, 5]
13
W:YB
3
-9
True
True
False
...
W@[2, 4]:1 + AB@[2, 5]:4 + AB@[2, 6]:8
pendant_pendant_sum
sole_8knot
5 rows × 31 columns
Code
```{python}aKFGName = 'AK001'from fieldmark_figure8knots import FieldmarkFigure8Knotsfigure8knot_fieldmark = FieldmarkFigure8Knots() aDF = figure8knot_fieldmark.relations_df()khipu_df = aDF[aDF['kfg_name']==aKFGName].fillna('')khipu_df = khipu_df[khipu_df['sum_type'].str.len() > 0]print("Figure 8 Knot Cords with Sum Indicators for AK001")khipu_df.head(10)```
Figure 8 Knot Cords with Sum Indicators for AK001
kfg_name
cord_name
cord_value
cord_color
eight_knot_type
is_subsidiary
is_sum_match
sum_type
handedness
sum_cord_name
num_summands
is_edge_match
is_neighbor_match
match_side
is_parity_bit
summand_string
0
AK001
p18
1
W:YB:G
sole_8knot
False
True
pendant_pendant_sums
left
p33
14
True
False
left
True
p18 + p19 + p20 + p21 + p22 + p23 + p24 + p25 ...
1
AK001
p24
11
W
trailing_8knot
False
True
pendant_pendant_sums
left
p24
3
False
True
right
False
p21 + p22 + p23
2
AK001
p24
11
W
trailing_8knot
False
True
pendant_pendant_sums
left
p37
3
True
False
left
False
p24 + p25 + p26
3
AK001
p28
1
W
sole_8knot
False
True
pendant_pendant_sums
left
p38
3
True
False
left
True
p28 + p29 + p30
Appendix.
One question to ask is what if figure8knots occur over a khipu because of 1 being the last digit
We’ve already seen above that figure8knots are NOT uniformly distributed over a summand range, but instead bunched at the “edges”. If a khipu’s numbers are “randomly distributed” then there is a 1% chance of a sole 8 knot occuring every 100 cords. Clearly the frequency of sole 8 knot cords is not that:
```{python}num_pendant_cords = the_khipu_df['num_pendant_cords'].to_list()num_sole_8knots = the_khipu_df['num_sole_8knot_cords'].to_list()pct_sole_8knots = [round(100.0*float(num_sole_8knots[i])/float(num_pendant_cords[i]),1) for i in range(len(num_pendant_cords))]pct_sole_8knots_df = pd.DataFrame({'kfg_name':eightknot_kfg_names, 'num_pendant_cords':num_pendant_cords, 'num_sole_8knots':num_sole_8knots, 'pct_sole_8knots':pct_sole_8knots}) import utils_math as umathprint("Statistics for % Sole 8 Knot Cords vs Pendant Cords")print(umath.get_statistics(pct_sole_8knots))fig = (px.scatter(pct_sole_8knots_df, x='num_pendant_cords', y='num_sole_8knots', color='pct_sole_8knots', color_continuous_scale='Bluered_r', log_x=True, log_y=True, title="By Khipu - # Pendant Cords vs # Sole 8 Knot Cords - Hover over Dot for Detail", labels={'num_pendant_cords':'# Pendant Cords (Log scale)', 'num_sole_8knots':'# Sole Figure-8-Knot Cords (Log scale)', 'pct_sole_8knots': '% Sole 8 Knot Cords vs Pendant Cords', 'kfg_name':'Khipu Name', }, width=944, height=944, trendline="ols", hover_data=['num_pendant_cords', 'num_sole_8knots', 'pct_sole_8knots', 'kfg_name'])).show()```
Statistics for % Sole 8 Knot Cords vs Pendant Cords
{'min': 0.0, 'mean': 14.603915662650602, 'median': 3.1500000000000004, 'max': 400.0, 'stddev': 31.583377881412815, 'range': 400.0, 'spread': 0.15791688940706408}
So clearly Sole8Knots are occuring at a much higher rate than 1% (14.6%!), with a trendline of 11%.
A similar line of reasoning can occur with trailing 8 knots. For example in 100 cords we have a 10% chance of getting cords that end with 1 (ie. 01,11,21,…91). Here we have to find trailing knot cords whose cord value ends in 1. (ie. the last eight knot is not added to the penultimate knot).
Code
```{python}# Collect all trailing 8 knot cords which end in a 1 digitthe_8knotcords_df = figure8knot_fieldmark.relations_df()pendant_trailing8knot_cords_mask = (the_8knotcords_df['is_subsidiary']==False) & (the_8knotcords_df['eight_knot_type']=='trailing_8knot')pendant_trailing8knot_cords_df = the_8knotcords_df[pendant_trailing8knot_cords_mask] print(f"Number of Pendant Trailing 8 Knot Cords ending in '1': {len(pendant_trailing8knot_cords_df)}")```
Number of Pendant Trailing 8 Knot Cords ending in '1': 2920
Code
```{python}ends_in_one_mask = [str(cord_value).endswith('1') for cord_value in pendant_trailing8knot_cords_df['cord_value'].tolist()]ends_in_one_df = pendant_trailing8knot_cords_df[ends_in_one_mask]ends_in_one_df.head()print(f"Number of Trailing 8 Knot Cords ending in '1': {len(ends_in_one_df)}")```
Number of Trailing 8 Knot Cords ending in '1': 2028
```{python}print("Statistics for % Trailing 8 Knot Cords ending in 1 vs Pendant Cords")print(umath.get_statistics(trailing8knot_1s_cords_df['pct_trailing8knot_cords'].to_list()))fig = (px.scatter(trailing8knot_1s_cords_df, x='num_pendant_cords', y='num_trailing8knot_1s_cords', color='pct_trailing8knot_cords', color_continuous_scale='Bluered_r', log_x=True, log_y=True, title="By Khipu - # Pendant Cords vs # Sole 8 Knot Cords - Hover over Dot for Detail", labels={'num_pendant_cords':'# Pendant Cords (Log scale)', 'num_trailing8knot_1s_cords':'# Trailing Figure-8-Knot Cords (Log scale)', 'pct_trailing8knot_cords': '% Trailing 8 Knot Cords vs Pendant Cords', 'kfg_name':'Khipu Name', }, width=944, height=944, trendline="ols", hover_data=['num_pendant_cords', 'num_trailing8knot_1s_cords', 'pct_trailing8knot_cords', 'kfg_name'])).show()```
Statistics for % Trailing 8 Knot Cords ending in 1 vs Pendant Cords
{'min': 0, 'mean': 7.828488372093023, 'median': 6.0, 'max': 58, 'stddev': 6.965320344696113, 'range': 58, 'spread': 0.24018346016193493}
Here we see a closer match - a mean of 7.8% of the pendant cords are trailing 8-knot cords ending in ‘1’, with a standard deviation of 7%, with a skeptically extracted trendline of only 4%. While this might argue against trailing 8 knots being a significant marker, there is this curious issue as to how the existing trailing 1’s gravitate to the edges of a summand range.