KFG Data Completeness


KFG Data Completeness

Now that we have a database of khipus, itโ€™s a good time to review how complete the data is. For example, how many khipus have cords with knots, with known colors, etc. The current of data to inventory includes:

  • Cords With Known Colors
  • Cords with Known Cord Ply/Spin
  • Cords with Known Cord Attachments
  • Khipus w/at Least 1 Knot (aka Zero Knot Khipus)
  • Knots with Known Twists
  • Long Knots with Known Axis Orientation (for Long Knots)

Letโ€™s evaluate each of these in turn. Weโ€™ll look only at Pendants for now in interests of making the search easier. Similarly, weโ€™ll only list the number of khipus that have at least some data. More detail is available for completeness by viewing the Fieldmarks Browser. For example, the Browser shows the three khipus without any Ascher Colors at the bottom of the (sorted) #Ascher Colors Fieldmark.

All Khipus

Start with all the khipus.

Code
(khipu_dict, all_khipus) = kamayuq.fetch_khipus()
print(f"# of All Khipus is {ku.pct_kfg_khipus(len(all_khipus))}")
# of All Khipus is 650 (100%)

Khipus with no Colors

How many khipus have not measured their colors?

Code
no_color_khipus = []
def satisfaction_condition(aCord):
    return aCord.longest_ascher_color()=="PK" or aCord.longest_ascher_color() == ""

for aKhipu in all_khipus:
    if all([satisfaction_condition(aCord) for aCord in aKhipu[:,:]]):
        no_color_khipus.append(aKhipu.name())
        
print(f"# of Khipus with No Known Color is  {ku.pct_kfg_khipus(len(no_color_khipus))}")
khipu_rep = ku.multiline(no_color_khipus, continuation_char="\n ")
print(f"No Color Khipus =\n{khipu_rep}")
# of Khipus with No Known Color is  3 (0%)
No Color Khipus =
['AS073', 'AS187', 'AS072']

Khipus with No Known Cord Ply/Spin

Code
khipus_by_cord_ply = {}
for aKhipu in all_khipus:
    if num_khipu_cords := aKhipu.num_cc_cords():
        khipus_by_cord_ply[aKhipu.name()] = (aKhipu.num_s_cords() + aKhipu.num_z_cords())/num_khipu_cords
    else:
        khipus_by_cord_ply[aKhipu.name()] = 0
        
khipus_by_cord_ply = dict(sorted(khipus_by_cord_ply.items(), key=lambda x:x[1]))
zero_cord_ply_khipus = [key for key in khipus_by_cord_ply.keys() if khipus_by_cord_ply[key]==0 ]
num_zero_cord_ply_khipus = len(zero_cord_ply_khipus)
print(f"# of Khipus with No Known Cord Ply/Spin is {ku.pct_kfg_khipus(num_zero_cord_ply_khipus)}")

khipu_rep = ku.multiline(zero_cord_ply_khipus, line_length=120, continuation_char="\n ")
print(f"Zero Cord Ply Khipus =\n{khipu_rep}")
# of Khipus with No Known Cord Ply/Spin is 136 (21%)
Zero Cord Ply Khipus =
['AS010', 'AS011', 'AS012', 'AS013', 'AS014', 'AS015', 'AS016', 'AS017', 'AS018', 'AS019', 'AS020', 'AS021', 'AS023',
 'AS024', 'AS025', 'AS026A', 'AS026B', 'AS027', 'AS028', 'AS029', 'AS035C', 'AS035D', 'AS036', 'AS037', 'AS039', 'AS041',
 'AS042', 'AS043', 'AS044', 'AS045', 'AS048', 'AS050', 'AS054', 'AS055', 'AS059', 'AS060', 'AS061/MA036', 'AS062',
 'AS063', 'AS063B', 'AS064', 'AS065', 'AS065B', 'AS066', 'AS069', 'AS071', 'AS073', 'AS077', 'AS081', 'AS082', 'AS083',
 'AS085', 'AS089', 'AS090/N2', 'AS092', 'AS093', 'AS094', 'AS101 - Part 1', 'AS101 - Part 2', 'AS110', 'AS111', 'AS112',
 'AS115', 'AS122', 'AS125', 'AS128', 'AS129', 'AS132', 'AS133', 'AS134', 'AS137', 'AS139', 'AS142', 'AS153', 'AS155',
 'AS156', 'AS157', 'AS158', 'AS159', 'AS160', 'AS164', 'AS168', 'AS169', 'AS171', 'AS172', 'AS173', 'AS174', 'AS177',
 'AS178', 'AS182', 'AS182B', 'AS183', 'AS184', 'AS185', 'AS186', 'AS187', 'AS188', 'AS189', 'AS201', 'AS202', 'AS203',
 'AS204', 'AS205', 'AS206', 'AS207A', 'AS207B', 'AS207C', 'AS209', 'AS210', 'AS211', 'AS212', 'AS213', 'AS214', 'AS215',
 'AS215F', 'AS35A', 'AS35B', 'HP052', 'UR1033A', 'UR1034', 'UR1040', 'UR1052', 'UR1127', 'UR1141', 'AS001', 'AS002',
 'AS003', 'AS004', 'AS005', 'AS006', 'AS007', 'AS008', 'AS009', 'AS072', 'KH0058', 'KH0080']

Khipus with No Known Cord Attachment

Code
khipus_by_cord_attachment = {}
for aKhipu in all_khipus:
    if num_khipu_cords := aKhipu.num_pendant_cords():
        khipus_by_cord_attachment[aKhipu.name()] = (aKhipu.num_top_cords() + aKhipu.num_recto_cords() + aKhipu.num_verso_cords())/num_khipu_cords
    else:
        khipus_by_cord_attachment[aKhipu.name()] = 0
        
khipus_by_cord_attachment = dict(sorted(khipus_by_cord_attachment.items(), key=lambda x:x[1]))
zero_cord_attachment_khipus = [key for key in khipus_by_cord_attachment.keys() if khipus_by_cord_attachment[key]==0 ]
num_zero_cord_attachment_khipus = len(zero_cord_ply_khipus)
print(f"# of Khipus with No Known Cord Attachment is {ku.pct_kfg_khipus(num_zero_cord_attachment_khipus)}")

khipu_rep = ku.multiline(zero_cord_attachment_khipus, line_length=120, continuation_char="\n ")
print(f"Zero Cord Attachment Khipus =\n{khipu_rep}")
# of Khipus with No Known Cord Attachment is 136 (21%)
Zero Cord Attachment Khipus =
['AS011', 'AS012', 'AS014', 'AS015', 'AS016', 'AS017', 'AS018', 'AS019', 'AS020', 'AS023', 'AS024', 'AS025', 'AS026A',
 'AS026B', 'AS027', 'AS028', 'AS029', 'AS035C', 'AS035D', 'AS036', 'AS037', 'AS039', 'AS041', 'AS042', 'AS043', 'AS045',
 'AS048', 'AS050', 'AS054', 'AS055', 'AS059', 'AS060', 'AS062', 'AS063', 'AS063B', 'AS064', 'AS065', 'AS065B', 'AS069',
 'AS071', 'AS073', 'AS077', 'AS081', 'AS082', 'AS083', 'AS085', 'AS089', 'AS090/N2', 'AS092', 'AS093', 'AS094', 'AS101 -
 Part 1', 'AS101 - Part 2', 'AS110', 'AS111', 'AS112', 'AS122', 'AS125', 'AS128', 'AS129', 'AS132', 'AS133', 'AS134',
 'AS137', 'AS139', 'AS142', 'AS153', 'AS155', 'AS156', 'AS157', 'AS158', 'AS159', 'AS160', 'AS164', 'AS168', 'AS169',
 'AS170', 'AS171', 'AS172', 'AS173', 'AS174', 'AS177', 'AS178', 'AS182', 'AS182B', 'AS183', 'AS184', 'AS185', 'AS186',
 'AS187', 'AS188', 'AS189', 'AS201', 'AS202', 'AS203', 'AS204', 'AS205', 'AS206', 'AS207B', 'AS207C', 'AS209', 'AS210',
 'AS211', 'AS213', 'AS214', 'AS215F', 'AS35A', 'AS35B', 'UR040', 'UR041', 'UR042', 'UR051', 'UR084', 'UR1033A', 'UR1034',
 'UR1040', 'UR1097', 'UR1098', 'UR1099', 'UR1100', 'UR1102', 'UR1103', 'UR1105', 'UR1106', 'UR1107', 'UR1108', 'UR1109',
 'UR1113', 'UR1114', 'UR1116', 'UR1117', 'UR1118', 'UR1119', 'UR1120', 'UR1121', 'UR1123', 'UR1124', 'UR1124 Detail 1',
 'UR1126', 'UR1127', 'UR1130', 'UR1131', 'UR1135', 'UR1136', 'UR1138', 'UR1140', 'UR1141', 'UR1143', 'UR1144', 'UR1145',
 'UR1146', 'UR1147', 'UR1148', 'UR1149', 'UR1150', 'UR1151', 'UR1152', 'UR1154', 'UR1161', 'UR1162A', 'UR1162B',
 'UR1163', 'UR1165', 'UR1166', 'UR1167', 'UR1175', 'UR1176', 'UR1179', 'UR1180', 'UR127', 'UR129', 'UR132', 'UR215',
 'AS005', 'AS008', 'AS009', 'KH0058', 'KH0080', 'UR050', 'UR052', 'UR054', 'UR055', 'UR110', 'UR112', 'UR144']

Khipus with no Knots

How many Khipus have no knots?

Code
## Zero Knot Khipus
def satisfaction_condition(aCord):
    return aCord.knotted_value()==0

zero_knot_khipus = []
for aKhipu in all_khipus:
    if all([satisfaction_condition(aCord) for aCord in aKhipu[:,:]]):
        zero_knot_khipus.append(aKhipu.name())
        
print(f"# of Khipus with No Knots is {ku.pct_kfg_khipus(len(zero_knot_khipus))}")

khipu_rep = ku.multiline(zero_knot_khipus, line_length=120, continuation_char="\n ")
print(f"Zero Knot Khipus =\n{khipu_rep}")
# of Khipus with No Knots is 14 (2%)
Zero Knot Khipus =
['AS025', 'HP025', 'HP026', 'HP028', 'UR070', 'UR071', 'UR082', 'UR103', 'UR158', 'UR179', 'UR185', 'UR216', 'HP048',
 'QU001']

Khipus with no Knot Twists

How many Khipus have knots with unrecorded twists?

Code
khipus_by_knot_twist = {}
for aKhipu in all_khipus:
    if num_khipu_knots := aKhipu.num_knots():
        khipus_by_knot_twist[aKhipu.name()] = (aKhipu.num_s_knots() + aKhipu.num_z_knots())/num_khipu_knots
    else:
        khipus_by_knot_twist[aKhipu.name()] = 0
        
khipus_by_knot_twist = dict(sorted(khipus_by_knot_twist.items(), key=lambda x:x[1]))
zero_knot_twist_khipus = [key for key in khipus_by_knot_twist.keys() if khipus_by_knot_twist[key]==0 ]
num_zero_knot_twist_khipus = len(zero_knot_twist_khipus)
print(f"# of Khipus with No Known Knot Twist is {ku.pct_kfg_khipus(num_zero_knot_twist_khipus)}")

khipu_rep = ku.multiline(zero_knot_twist_khipus, line_length=120, continuation_char="\n ")
print(f"No Known Knot Twist Khipus =\n{khipu_rep}")
# of Khipus with No Known Knot Twist is 139 (21%)
No Known Knot Twist Khipus =
['AS010', 'AS011', 'AS012', 'AS013', 'AS014', 'AS015', 'AS016', 'AS017', 'AS018', 'AS019', 'AS020', 'AS021', 'AS023',
 'AS024', 'AS025', 'AS026A', 'AS026B', 'AS027', 'AS028', 'AS029', 'AS035C', 'AS035D', 'AS036', 'AS037', 'AS039', 'AS041',
 'AS042', 'AS043', 'AS044', 'AS045', 'AS048', 'AS050', 'AS054', 'AS055', 'AS059', 'AS060', 'AS061/MA036', 'AS062',
 'AS063', 'AS063B', 'AS064', 'AS065', 'AS065B', 'AS066', 'AS069', 'AS071', 'AS073', 'AS077', 'AS081', 'AS082', 'AS083',
 'AS085', 'AS089', 'AS090/N2', 'AS092', 'AS093', 'AS094', 'AS101 - Part 1', 'AS101 - Part 2', 'AS110', 'AS111', 'AS112',
 'AS115', 'AS122', 'AS125', 'AS128', 'AS129', 'AS132', 'AS133', 'AS134', 'AS137', 'AS139', 'AS142', 'AS153', 'AS155',
 'AS156', 'AS157', 'AS158', 'AS159', 'AS160', 'AS164', 'AS168', 'AS169', 'AS170', 'AS171', 'AS172', 'AS173', 'AS174',
 'AS177', 'AS178', 'AS182', 'AS182B', 'AS183', 'AS184', 'AS185', 'AS186', 'AS187', 'AS188', 'AS189', 'AS201', 'AS202',
 'AS203', 'AS204', 'AS205', 'AS206', 'AS207A', 'AS207B', 'AS207C', 'AS209', 'AS210', 'AS211', 'AS212', 'AS213', 'AS214',
 'AS215', 'AS215F', 'AS35A', 'AS35B', 'HP025', 'HP026', 'HP028', 'UR070', 'UR071', 'UR082', 'UR158', 'AS001', 'AS002',
 'AS003', 'AS004', 'AS005', 'AS006', 'AS007', 'AS008', 'AS009', 'AS072', 'HP048', 'KH0058', 'KH0080', 'QU001']

Khipus with Long Knots with Known Axis Orientation

How many Khipus record axis orientation of long knots?

Code
import khipu_cord

CSV_dir = f"{kq.project_directory()}/data/CSV"
axis_df = pd.read_csv(f"{CSV_dir}/knot_clean.csv")

def has_old_orientation(x): return isinstance(x, str) and x.startswith("AX")
long_knot_direction_mask = [has_old_orientation(orientation) for orientation in axis_df.axis_orientation.values ]
cord_ids = list(axis_df[long_knot_direction_mask].cord_id.values)
khipus_KFG_old_style = list(set([khipu_cord.fetch_cord(cord_id).khipu_name for cord_id in cord_ids]))

def has_new_orientation(x): return isinstance(x, str) and (x.startswith("D") or x.startswith("U") or x.startswith("AX"))
long_knot_direction_mask = [has_new_orientation(orientation) for orientation in axis_df.axis_orientation.values ]
cord_ids = list(axis_df[long_knot_direction_mask].cord_id.values)
khipus_KFG_new_style = list(set([khipu_cord.fetch_cord(cord_id).khipu_name for cord_id in cord_ids]))

khipus_with_axis_orientation = sorted(list(set(khipus_KFG_old_style +khipus_KFG_new_style)))
num_zero_axis_orientation_khipus = len(all_khipus) - len(khipus_with_axis_orientation)
print(f"# of Khipus with No Known Long Knot Axis_orientation is {ku.pct_kfg_khipus(num_zero_axis_orientation_khipus)}")

khipu_rep = ku.multiline(khipus_with_axis_orientation, line_length=120, continuation_char="\n ")
print(f"KNOWN Axis-Orientation Khipus =\n{khipu_rep}")
# of Khipus with No Known Long Knot Axis_orientation is 315 (48%)
KNOWN Axis-Orientation Khipus =
['AS028', 'AS054', 'AS067/MA029', 'AS071', 'AS074', 'AS075', 'AS076', 'AS078', 'AS079', 'AS080', 'AS093', 'AS191',
 'AS192', 'AS193', 'AS194', 'AS195', 'AS196', 'AS197', 'AS198', 'AS199', 'AS200', 'HP001', 'HP002', 'HP003', 'HP004',
 'HP005', 'HP006', 'HP007', 'HP008', 'HP009', 'HP010', 'HP011', 'HP012', 'HP013', 'HP014', 'HP015', 'HP016', 'HP017',
 'HP018', 'HP019', 'HP020', 'HP021', 'HP022', 'HP023', 'HP024', 'HP027', 'HP029', 'HP030', 'HP031', 'HP032', 'HP033',
 'HP034', 'HP036', 'HP037', 'HP038', 'HP039', 'HP040', 'HP041', 'HP042', 'HP043', 'HP044', 'HP046 A', 'HP046 B', 'HP047',
 'HP049', 'HP050', 'HP051 A', 'HP051 B', 'HP053', 'HP054', 'HP056', 'HP057', 'JC001', 'JC002', 'JC003', 'JC004', 'JC005',
 'JC006', 'JC007', 'JC008', 'JC009', 'JC010', 'JC011', 'JC012', 'JC013', 'JC014', 'JC015', 'JC017', 'JC018', 'JC019',
 'JC021', 'JC022', 'JC023', 'LL01', 'MM001', 'MM002', 'MM003', 'MM004', 'MM005', 'MM006/AN001', 'MM007/AN002', 'MM008',
 'MM009', 'MM010', 'MM011', 'MM012', 'MM013', 'MM014', 'MM015', 'MM016', 'MM017', 'MM018', 'MM019', 'MM020', 'MM021',
 'MM1086', 'UR001', 'UR002', 'UR003', 'UR004', 'UR005', 'UR006', 'UR007', 'UR008', 'UR009', 'UR010', 'UR011', 'UR012',
 'UR013', 'UR014', 'UR015', 'UR016', 'UR017', 'UR018', 'UR019', 'UR020', 'UR021', 'UR022', 'UR034', 'UR038', 'UR051',
 'UR056A', 'UR057', 'UR059', 'UR060', 'UR061', 'UR062', 'UR063', 'UR064', 'UR066', 'UR067', 'UR069', 'UR072', 'UR074',
 'UR075', 'UR076', 'UR077', 'UR078', 'UR079', 'UR080', 'UR081', 'UR085', 'UR086', 'UR087', 'UR088', 'UR089', 'UR090',
 'UR091', 'UR092', 'UR093', 'UR094', 'UR095', 'UR096', 'UR097', 'UR098', 'UR099', 'UR100', 'UR101', 'UR102', 'UR1031',
 'UR104', 'UR105', 'UR1051', 'UR1052', 'UR1053', 'UR1057', 'UR1058', 'UR106', 'UR107', 'UR108', 'UR1084', 'UR109',
 'UR1104', 'UR111', 'UR114', 'UR115', 'UR116A', 'UR117D', 'UR120', 'UR128', 'UR129', 'UR130', 'UR131A', 'UR131B',
 'UR131C', 'UR132', 'UR134', 'UR143', 'UR146', 'UR149', 'UR152', 'UR161', 'UR162', 'UR163', 'UR168', 'UR169', 'UR170',
 'UR171', 'UR172', 'UR173', 'UR174', 'UR175', 'UR176', 'UR177', 'UR178', 'UR180', 'UR182', 'UR183', 'UR184', 'UR185',
 'UR186', 'UR187', 'UR188', 'UR189', 'UR191', 'UR192', 'UR194', 'UR195', 'UR196', 'UR197', 'UR198', 'UR199', 'UR200',
 'UR201', 'UR202', 'UR203', 'UR204', 'UR205', 'UR206', 'UR207', 'UR208', 'UR209', 'UR210', 'UR211', 'UR212', 'UR213',
 'UR214', 'UR215', 'UR216', 'UR217', 'UR218', 'UR219', 'UR220', 'UR221', 'UR222', 'UR223', 'UR225', 'UR226', 'UR228',
 'UR229', 'UR230', 'UR231', 'UR232', 'UR233', 'UR234', 'UR235', 'UR236', 'UR237', 'UR238', 'UR239', 'UR240', 'UR241',
 'UR242', 'UR243', 'UR244', 'UR245', 'UR246', 'UR247', 'UR248', 'UR249', 'UR250', 'UR251', 'UR252', 'UR254', 'UR255',
 'UR256', 'UR257', 'UR258', 'UR259', 'UR260', 'UR261', 'UR262', 'UR263', 'UR264', 'UR265', 'UR266', 'UR267A', 'UR267B',
 'UR268', 'UR269', 'UR270', 'UR271', 'UR272', 'UR273A', 'UR273B', 'UR274A', 'UR274B', 'UR275', 'UR276', 'UR277', 'UR278',
 'UR279', 'UR281', 'UR282', 'UR283', 'UR284', 'UR285', 'UR286', 'UR287', 'UR288', 'UR289', 'UR290', 'UR291A', 'UR293',
 'UR294']