Mean Cord Value


An examination of the mean cord value of all pendant cords in a khipu.

This seems a simple idea. What is the mean cord value of all the cords (including top cords, subsidiary cords, etc.) of a khipu. Yet this simple idea reveals a lot.

1. Search Criteria:

For each khipu what is the mean of all cords’ values (including pendants, subsidiaries, top cords, etc.)

2. Significance Criteria:

Here we’ll assume above the mean as a significant criteria. As you can see below the top 7 khipu have very high cord values, significantly elevating the mean.

3. Summary Results:

Measure Result
Number of Khipus That Match 623 (96%)
Number of Significant Khipus 24 (4%)
Five most Significant Khipu UR257, UR188, UR1143, UR1104, UR1119
Image Quilt Click here

4. Summary Charts:

Code
# Initialize plotly
plotly.offline.init_notebook_mode(connected = False);

# Read in the Fieldmark and its associated dataframe and match dictionary
from fieldmark_khipu_summary import Fieldmark_Mean_Cord_Value
aFieldmark = Fieldmark_Mean_Cord_Value()
fieldmark_dataframe = aFieldmark.dataframes[0].dataframe
raw_match_dict = aFieldmark.raw_match_dict()
Code
# Plot Matching khipu
matching_khipus = aFieldmark.matching_khipus() 
matching_values = [raw_match_dict[aKhipuName] for aKhipuName in matching_khipus]
matching_df =  pd.DataFrame(list(zip(matching_khipus, matching_values)), columns =['KhipuName', 'Value'])
fig = px.bar(matching_df, x='KhipuName', y='Value', labels={"KhipuName": "Khipu Name", "Value": "Mean Cord Value", }, 
            title=f"<b>{ku.pct_kfg_khipus(len(matching_khipus))}</b> Matching Khipu for Mean Cord Value",  width=940, height=500).update_layout(showlegend=True).show()
Code
# Plot Significant khipu
significant_khipus = aFieldmark.significant_khipus()
significant_values = [raw_match_dict[aKhipuName] for aKhipuName in significant_khipus]
significant_df =  pd.DataFrame(list(zip(significant_khipus, significant_values)), columns =['KhipuName', 'Value'])
fig = px.bar(significant_df, x='KhipuName', y='Value', labels={"KhipuName": "Khipu Name", "Value": "Mean Cord Value", },
             title=f"<b>{ku.pct_kfg_khipus(len(significant_khipus))}</b> Significant Khipu for Mean Cord Value", width=940, height=450).update_layout(showlegend=True).show()

5. Exploratory Data Analysis

5.1 Cord Values By Occurrence

How do cord values distribute by occurrence?

Code
# Khipu Imports#
import khipu_kamayuq as kamayuq  # A Khipu Maker is known (in Quechua) as a Khipu Kamayuq
import khipu_qollqa as kq
import khipu_utils as ku
# Load khipus
all_khipus = [aKhipu for aKhipu in kamayuq.fetch_all_khipus().values()]

all_pendant_cords = []
for aKhipu in all_khipus: all_pendant_cords += aKhipu[:,:]
zero_value_pendant_cords = [aCord for aCord in all_pendant_cords if aCord.knotted_value()==0 ]
non_zero_pendant_cords = [aCord for aCord in all_pendant_cords if aCord.knotted_value() > 0]
print(f"{len(all_pendant_cords)}  pendant cords exist")
print(f"{len(zero_value_pendant_cords)} zero value pendant cords exist")
print(f"{len(non_zero_pendant_cords)} non-zero value pendant cords exist")
41671  pendant cords exist
13206 zero value pendant cords exist
28465 non-zero value pendant cords exist
Code
cord_values = [aCord.knotted_value() for aCord in non_zero_pendant_cords]
value_counter = Counter(cord_values)
cord_value_df =  pd.DataFrame(value_counter.most_common(), columns =['cord_value', 'occurrence'])
cord_value_df
cord_value occurrence
0 1 3045
1 2 2144
2 10 1492
3 3 1404
4 4 1366
... ... ...
1709 2383 1
1710 24146 1
1711 2497 1
1712 36024 1
1713 6300 1
Code
fig = px.bar(cord_value_df, x='cord_value', y='occurrence', log_x=True, 
             labels={"cord_value": "Cord Value", "occurrence": "Num Times Value Occurs", },
             title="Cord Values by Occurrence", width=940, height=450).update_layout(showlegend=True).show()

In line with Benford’s Law, you can see that cord values of 1, occur more than 2, 2 occur more than 3, etc. and that there’s spikes at 10, 20, etc., and 100, 200, etc.

5.2 Mean Cord Values vs Ascher Relationships

In the analysis of pendant-pendant sum relationships, where one pendant’s cord value is the sum of another set of contiguous cords, I noted how big mean-cord-value khipus had so few pendant-pendant-sum relationships. Let’s review that for all Ascher sum relationships.

Code
(khipu_dict, all_khipus) = kamayuq.fetch_khipus()
ascher_sum_relations_df = pd.read_csv(f"{ku.fieldmarks_directory()}/CSV/ascher_pendant_relationships.csv")

def num_ascher_relations(khipu_name):
    num_relations = 0
    
    khipu_relation_df = ascher_sum_relations_df[ascher_sum_relations_df.khipu_name == khipu_name]
    if len(khipu_relation_df) > 0:
        khipu_record = khipu_relation_df.iloc[0]
        num_relations = (khipu_record.num_pendant_pendant_sum 
                         + khipu_record.num_indexed_pendant_sum
                         + khipu_record.num_pendant_pendants_color_sum
                         + khipu_record.num_cluster_sum_bands
                         + khipu_record.num_cluster_cluster_sum
                         )
    return round(num_relations)

khipu_names = [ku.strip_html(aref) for aref in list(ascher_sum_relations_df.name.values)]
ascher_sum_relations_df['khipu_name'] = khipu_names

relations_by_cord_value = [(khipu_name, raw_match_dict[khipu_name], num_ascher_relations(khipu_name)) for khipu_name in matching_khipus]
relations_by_cord_value_df = pd.DataFrame(relations_by_cord_value, columns=['name', 'mean_cord_value', 'num_ascher_relations'])
relations_by_cord_value_df.sort_values(by=['mean_cord_value'], inplace=True, ascending=False)
relations_by_cord_value_df.head(20)
name mean_cord_value num_ascher_relations
0 UR257 26324 0
1 UR188 13918 2
2 UR1143 12071 5
3 UR1104 9786 0
4 UR1119 9631 0
... ... ... ...
15 HP010 2348 0
16 HP001 2003 0
17 AS129 1914 0
18 UR164 1907 0
19 UR248 1809 0
Code
size_vec = [x for x in list(relations_by_cord_value_df.num_ascher_relations.values)]
fig = px.scatter(relations_by_cord_value_df, y='num_ascher_relations', x='mean_cord_value', log_x=True,
             #size=size_vec, 
             color='num_ascher_relations', 
             labels={"num_ascher_relations": "Number of Ascher Relations", "mean_cord_value": "Mean Cord Value (Log_10)"},
             hover_name='name', hover_data=['mean_cord_value', 'num_ascher_relations'], 
             title="Number of Ascher Relations by Mean Cord Values", width=940, height=500).update_layout(showlegend=True).show()

This shows, once again, how large cord-value khipus are more of an “executive summary” and less of a working man’s khipu.

5.3 Mean Cord Values vs Untied Knots

Manuel Medrano suggested the following hypothesis: If there are khipus with untied knots (ie. knots that had been tied and are now untied), then that would indicate that they are likely “working” khipus, and not presentation khipus, as noted in the above section.

Let’s examine that hyppothesis. First a search of the database CSV files for “untied”, “unknotted” and “desanudado” knot reveals:

Code
untied_occurences = """
cord.csv:16:1000000,3000015,0.0000,0.0000,CN,U,3000006,0,U,1000005,1,1,2.000,32.000,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 06:44:23,2,nudo desanudado,S,,1,0,0
cord.csv:61:1000003,3000060,0.0000,0.0000,CN,K,1000003,0,V,1000027,5,7,0.000,38.000,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 09:56:27,1,(y un desanudado) -- cord includes evidence of a unknotting,S,,5,0,0
cord.csv:207:1000004,3000206,0.0000,0.0000,CN,U,1000004,0,R,1000059,9,115,0.000,33.500,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 15:01:12,1,nudo desanudado,S,,114,0,0
cord.csv:208:1000004,3000207,0.0000,0.0000,CN,K,1000004,0,V,1000060,1,116,0.000,40.000,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 15:01:43,1,nudo desanudado,S,,115,0,0
cord.csv:23537:1000292,3024405,0.0000,0.0000,CN,K,3023941,0,U,1007839,5,5,0.000,26.500,chandra,2011-12-23 09:44:41,chandra,2005-07-11 11:27:46,2,The knot on this khipu is partly untied.,S,,5,0,0
cord.csv:2768:1000022,3002912,0.0000,0.0000,CN,,1000022,0,V,1001020,1,135,0.000,0.000,katie,2011-11-23 19:42:40,gurton,2010-04-07 07:59:12,1,untied figure 8 knot?,S,PA,1,0,0
cord.csv:4383:1000023,3004539,0.0000,0.0000,CN,K,1000025,0,R,1001405,3,151,0.000,38.000,katie,2011-12-23 09:44:41,katie,2003-06-25 12:17:21,1,(knot untied),S,,145,0,0
cord.csv:54205:1000623,3056328,,0.0000,CN,K,1000623,,R,1019578,5,77,0.000,48.000,julia,2016-01-31 08:52:21,julia,2016-01-31 08:52:21,1,untied ,S,,,,
cord.csv:54221:1000623,3056344,,0.0000,CN,B,1000623,,R,1019580,3,93,0.000,41.500,julia,2016-01-31 08:52:21,julia,2016-01-31 08:52:21,1,untied ,S,,,,
cord.csv:5508:1000036,3005684,0.0000,0.0000,,K,1000036,0,U,1001792,3,5,0.000,36.500,katie,2011-12-23 09:44:41,katie,2003-06-30 09:48:07,1,Pendant 5 has a kink at 8.0 cm that appears to correspond to a 1s knot that was untied (not recent).,U,,5,0,0
cord.csv:5512:1000036,3005688,0.0000,0.0000,,K,1000036,0,U,1001793,1,9,0.000,37.500,katie,2011-12-23 09:44:41,katie,2003-06-30 09:50:01,1,Pendant 9 has a kink at 18.5 cm that appears to correspond to a 2L knot that was untied (not recent).,U,,9,0,0
cord.csv:5516:1000036,3005692,0.0000,0.0000,,K,1000036,0,U,1001793,5,13,0.000,28.500,katie,2011-12-23 09:44:41,katie,2003-06-30 09:52:07,1,Pendant 13 has a kink at 15.5 cm that appears to correspond to a 2L knot that was untied (not recent).,U,,13,0,0
cord.csv:5517:1000036,3005693,0.0000,0.0000,,K,1000036,0,U,1001793,6,14,0.000,24.500,katie,2011-12-23 09:44:41,katie,2003-06-30 09:52:41,1,Pendant 14 has a kink at 14.5 cm that appears to correspond to a 1E knot that was untied (not recent).,U,,14,0,0
cord.csv:5518:1000036,3005694,0.0000,0.0000,,K,1000036,0,U,1001794,1,15,0.000,25.500,katie,2011-12-23 09:44:41,katie,2003-06-30 09:53:21,1,Pendant 15 has a kink at 15.0 cm that appears to correspond to a 3L knot that was untied (not recent).,U,,15,0,0
cord.csv:23800:1000292,3024668,0.0000,0.0000,CN,K,3024057,0,U,1007927,3,3,1.000,38.500,chandra,2011-12-23 09:44:41,chandra,2005-07-22 11:28:19,2,This subsidiary may be unknotted.,S,,3,0,0
cord_level_1.csv:1717:1000022,3002912,0.0000,0.0000,CN,,1000022,0,V,1001020,1,135,0.000,0.000,1,untied figure 8 knot?,S,PA,1,1,katie,2011-11-23 19:42:40,gurton,2010-04-07 07:59:12
cord_level_1.csv:183:1000004,3000206,0.0000,0.0000,CN,U,1000004,0,R,1000059,9,115,0.000,33.500,1,nudo desanudado,S,,114,1,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 15:01:12
cord_level_1.csv:184:1000004,3000207,0.0000,0.0000,CN,K,1000004,0,V,1000060,1,116,0.000,40.000,1,nudo desanudado,S,,115,1,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 15:01:43
cord_level_1.csv:2874:1000023,3004539,0.0000,0.0000,CN,K,1000025,0,R,1001405,3,151,0.000,38.000,1,(knot untied),S,,145,1,katie,2011-12-23 09:44:41,katie,2003-06-25 12:17:21
cord_level_1.csv:37160:1000623,3056328,,0.0000,CN,K,1000623,,R,1019578,5,77,0.000,48.000,1,untied ,S,,,,julia,2016-01-31 08:52:21,julia,2016-01-31 08:52:21
cord_level_1.csv:37176:1000623,3056344,,0.0000,CN,B,1000623,,R,1019580,3,93,0.000,41.500,1,untied ,S,,,,julia,2016-01-31 08:52:21,julia,2016-01-31 08:52:21
cord_level_1.csv:47:1000003,3000060,0.0000,0.0000,CN,K,1000003,0,V,1000027,5,7,0.000,38.000,1,(y un desanudado) -- cord includes evidence of a unknotting,S,,5,1,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 09:56:27
cord_level_2.csv:3:1000000,3000015,0.0000,0.0000,CN,U,3000006,0,U,1000005,1,1,2.000,32.000,2,nudo desanudado,S,,1,1,1,6,cbrezine,2011-12-23 09:44:41,cbrezine,2003-05-29 06:44:23
cord_level_2.csv:5189:1000292,3024405,0.0000,0.0000,CN,K,3023941,0,U,1007839,5,5,0.000,26.500,2,The knot on this khipu is partly untied.,S,,5,5,1,83,chandra,2011-12-23 09:44:41,chandra,2005-07-11 11:27:46
khipu_notes.csv:527:1000247,cbrezine,2004-08-13 11:06:05,,0000-00-00 00:00:00,"There are no knots on this khipu, but at level 15 - 17 cm from primary cord there are indications on some strings that knots were untied. ","There are no knots on this khipu, but at level 15 - 17 cm from primary cord there are indications on some strings that knots were untied. "
khipu_notes.csv:528:1000247,cbrezine,2004-08-13 11:22:35,,0000-00-00 00:00:00,There are notations on the original notes about the position of untied knots. ,There are notations on the original notes about the position of untied knots. 
khipu_notes.csv:86:1000036,katie,2003-06-30 09:38:25,,0000-00-00 00:00:00,"Construction note: Several cords (5, 9, 13-15) are kinked just at the place where a knot cluster is expected as if knots were present but had been untied.  Because the color and texture of the cords are unmarred, any unknotting would not have been recent.  The kinks are sufficiently clear to be able to ""reconstruct"" the number and type of knots.  In no case does an actual knot cluster appear on a kinked cord at the level of the kink.  The listing contains the actual knots only.  Both the ""reconstructed"" knots (marked with *) and the actual knots are shown below.  No values are inputed to them as we do not know whether to combine them or replace one with the other.",
"""

Let’s find out the khipu names associated with those occurences:

Code
import csv

def fetch_csv_line(filename, line_number):
    CSV_file = f"{kq.project_directory()}/data/CSV/{filename}"
    lines = []
    with open(CSV_file, mode ='r')as file:
        csvFile = csv.reader(file)
        try:
            for line in csvFile:
               lines.append(line)
        except:
            pass
    
    try:
        theLine = lines[line_number-1]
    except:
        theLine = ""
    return theLine

ids = []
for line in untied_occurences.split("\n"):
    fields = line.split(":")
    if len(fields)>1:
        filename = fields[0]
        linenum = int(fields[1])
        csv_line = fetch_csv_line(filename, linenum)
        if len(csv_line)>0:
            ids.append(int(csv_line[0]))

khipu_ids = sorted(list(set(ids)))
untied_khipus = []
for anId in khipu_ids:
    try:
        kfg_name = kq.kfg_name_from_id(int(anId))
        untied_khipus.append(kfg_name)
    except:
        print(f"Unable to find kfg_name for {anId}")
untied_khipus
Unable to find kfg_name for 1000023
['UR019', 'UR018', 'UR010', 'UR021', 'AS214', 'UR070', 'UR113', 'UR278']

And … what are the mean cord values for these khipus?

Code
mean_cord_values = {aKhipuName: raw_match_dict[aKhipuName] for aKhipuName in untied_khipus}
mean_cord_values
{'UR019': 5,
 'UR018': 725,
 'UR010': 17,
 'UR021': 3,
 'AS214': 9,
 'UR070': 0,
 'UR113': 15,
 'UR278': 229}

So, yes. Of the few samples we have, those khipu’s cord’s untied knots are on the low end of the range for mean cord values.

6. Conclusion

The large (by cord value) khipus UR257, UR188, UR1143, UR1104, UR1119 and to some extent UR247 and UR161 are clearly in a field of their own, as is evident in viewing them in the Khipu Fieldmark Browser, when viewing them as a connected graph, or as shown above. When you are measuring something in the waranqa scale of 1000’s, those are unusual numbers - a high level summary khipu, perhaps.