Group-Group Sums


1. Number of Group-Group Sum Matches:

Groups whose sum of all its cords, including subsidiaries, match the sum of another group in the khipu.

Gary Urton mentions this fieldmark in the set of Census khipu, UR057, UR023, UR024, UR029, UR028, and UR027, knotted together as one giant khipu. In UR028, he notes how the sum of all the cords in one group, including subsidiaries, sums to 102, the the sum of all the cords in another group.

2. Search Criteria:

This one’s easy. Find all the groups whose sum whose sum of all its cords, including subsidiaries, match the sum of another group in the khipu.

Note that the search is constrained by these factors:

  • The sums must be greater than or equal to 21. Why 21? Because if we set the bar to 11 (the usual threshold) enough group sums exist in the 11-20 range to create random group sum results (high recall-low precision).
  • Not divisible by 10, or greater than or equal to 100.
  • Unlike Urton’s UR028 example, top cords are NOT included. 0therwise, this type of relationship would overlap with fieldmarks from Sum Top Cord or Double Sum Top Cords.
Code
import plotly

def is_significant_sum(self, aSum):
    if aSum >= 100: 
        return True
    elif aSum >= 11 and aSum % 10 != 0:
        return True
    else:
        return False

def search_matching_sum_groups(self, aKhipu):
    matching_sum_groups = []
    groups = aKhipu[:]
    group_sums = [(group,self.total_group_sum(group)) for group in groups]

    for index, item in enumerate(group_sums[:-1]):
        left_group, left_group_sum = item
        for right_group_index in range(index+1,len(group_sums)):
            right_group, right_group_sum = group_sums[right_group_index]
            if left_group_sum == right_group_sum and self.is_significant_sum(left_group_sum):
                matching_sum_groups.append((left_group, right_group))

    return matching_sum_groups

3. Significance Criteria:

In this case, due to the search constraints noted above, significance is num_sum_groups >= 1

4. Summary Results:

Measure Result
Number of Khipus That Match 111 (17%)
Number of Significant Khipus 111 (17%)
Five most Significant Khipu UR055, UR052, AS069, UR1109, AS066
XRay Image Quilt Khipu by Group-Group Sum Relationships
Database View Click here

5. 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_group_group_sum import FieldmarkGroupGroupSum
aFieldmark = FieldmarkGroupGroupSum()
fieldmark_dataframe = aFieldmark.dataframes[0].dataframe
raw_match_dict = aFieldmark.raw_match_dict()
#len(aFieldmark.dataframes[1].dataframe)
Code
import pandas as pd
import plotly.express as px

# 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": "Number of Group Sum Matches", },
             title=f"Significant Khipu ({len(significant_khipus)}) for Number of Group Sum Matches", width=944, height=450).update_layout(showlegend=True).show()

6. Exploratory Data Analysis:

While not occuring often, group group sums appear frequently enough that they bear examining and identifying. We know that 90 khipus have group group sums.

6.1 By Mean Cord Value

Code
khipu_sums_df = aFieldmark.dataframes[0].dataframe
sum_cord_df = aFieldmark.dataframes[1].dataframe
Code
title_str="Matching Sum Groups by Khipu (Size is Max Group Sum Value)"
fig = (px.scatter(khipu_sums_df, x="num_sum_groups", y="mean_sum",  log_y=True, 
                 size="max_sum", color="mean_sum",
                 labels={"mean_sum": "Mean Match Value", "num_sum_groups": "Number of Matching Sums"},
                 hover_name="kfg_name", hover_data=['num_sum_groups', 'min_sum', 'mean_sum', 'max_sum'], 
                 title=title_str,
                 width=944, height=944)
        .update_layout(showlegend=False)
        .show()
      )

We can see that most khipus have one or two pairs of matching sum groups. The range is 100 to 6000.

6.2 Distance between sum groups?

What is the distance between sum groups?

Code
title_str="Group Sums - Sum Value vs Distance between Groups"
fig = (px.scatter(sum_cord_df, x="group_distance", y="group_sum", log_y=True, 
                 #size="max_sum", color="mean_sum",
                 labels={"group_distance": "Distance between Groups", "group_sum": "Group Cord Sum"},
                 hover_name="kfg_name", hover_data=['group_distance', 'group_sum'], 
                 title=title_str,
                 width=944, height=944)
        .update_layout(showlegend=False)
        .show()
      )

Everything above 50 is our old mis-spliced friend AS069. Let’s remove that outlier.

Code
sum_cord_df = sum_cord_df[sum_cord_df.kfg_name != "AS069"]
title_str="Group Sums - Sum Value vs Distance between Groups"
fig = (px.scatter(sum_cord_df, x="group_distance", y="group_sum", log_y=True, 
                 #size="max_sum", color="mean_sum",
                 labels={"group_distance": "Distance between Groups", "group_sum": "Group Cord Sum (Log_10)"},
                 hover_name="kfg_name", hover_data=['group_distance', 'group_sum'], 
                 title=title_str,
                 width=944, height=944)
        .update_layout(showlegend=False)
        .show()
      )

And with that we see the same sort of familiar triangular distribution witnessed in indexed pendant sum handedness or subsidiary pendant sum handedness.

Next, let’s remove group group sums where the group lengths aren’t the same. Why? Because these are likely compound sums. For example say Group A has 3 cords which are sums of Group B’s 12 cord set made of 3 colors bands of 4 cords. This would count as a group group sum, and as three pendant pendant sums. Let’s remove those.

Code
equal_len_group_sums_df = sum_cord_df[sum_cord_df.left_num_group_cords == sum_cord_df.right_num_group_cords]
num_equal_len_group_khipus = len(set(list(equal_len_group_sums_df.kfg_name.values)))
title_str=f"{len(equal_len_group_sums_df)} Equal Length Group Sums over {num_equal_len_group_khipus} khipus - Sum Value vs Distance between Groups"
fig = (px.scatter(equal_len_group_sums_df, x="group_distance", y="group_sum", 
                 size="left_num_group_cords", color="left_num_group_cords",
                 labels={"left_num_group_cords":"# of Group Cords", "group_distance": "Distance between Groups", "group_sum": "Group Cord Sum"},
                 hover_name="kfg_name", hover_data=['group_distance', 'group_sum'], 
                 title=title_str,
                 width=944, height=944)
        .update_layout(showlegend=False)
        .show()
      )

We’re now left with a set of 33 khipus with interesting group sum pairs.

Let’s evaluate the location of group sum pairs.

Code
%%capture --no-display

title_str=f"<b>{len(equal_len_group_sums_df)} Equal-Length Sums by Position</b>" + \
          " : Size=#Cords, Color=Log_10(GroupCords Sum)"
color_vec = [math.log10(x) for x in list(equal_len_group_sums_df.group_sum.values)]
fig = (px.scatter(equal_len_group_sums_df, 
                  x="left_group_index", y="right_group_index", 
                  color=color_vec, size="left_num_group_cords",
                  labels={"color":"Log_10 of Group Cords Sum",
                          "left_num_group_cords":"# of Group Cords", 
                          "group_sum": "Group Cords Sum", 
                          "group_distance": "Distance between Groups",
                          "left_group_position":"Left Group Position", 
                          "right_group_position":"Right Group Position"},
                  hover_name="kfg_name", hover_data=['left_group_index', 'right_group_index', 'group_distance', 'group_sum'], 
                  title=title_str,
                  trendline="ols",
                  width=944, height=944)
        .update_layout(showlegend=False)
        .show()
      )

Well that’s a pretty clear relationship. The trendline indicates that generally, the right group position is about 5 cords away from the left cord position.

6.3 Banded vs Seriated

Does this sum relationship distribute over both seriated and banded khipus?

Code
khipu_sums_df.columns
sum_cord_df.columns
Index(['Unnamed: 0', 'kfg_name', 'group_sum', 'is_top_group',
       'is_duplicate_group', 'left_group_index', 'left_num_group_cords',
       'right_group_index', 'right_num_group_cords', 'group_distance',
       'cord_count_distance', 'left_group_summand_string',
       'right_group_summand_string'],
      dtype='object')
Code
import qollqa_chuspa as qc
(khipu_dict, all_khipus) = qc.fetch_khipus()

def banded_color(kfg_name): 
    aKhipu = khipu_dict[kfg_name]
    is_banded = aKhipu.num_banded_groups() > khipu_dict[kfg_name].num_seriated_groups()
    return 0.0 if is_banded else 1.0
def banded_ratio(kfg_name):
    aKhipu = khipu_dict[kfg_name]
    total_groups = aKhipu.num_cord_groups()
    return aKhipu.num_banded_groups()/total_groups if total_groups > 0 else 0

khipu_sums_df['banded_color'] = [banded_color(x) for x in khipu_sums_df.kfg_name.values]
khipu_sums_df['banded_ratio'] = [banded_ratio(x) for x in khipu_sums_df.kfg_name.values]
khipu_sums_df['num_banded_groups'] = [khipu_dict[x].num_banded_groups() for x in khipu_sums_df.kfg_name.values]
khipu_sums_df['num_seriated_groups'] = [khipu_dict[x].num_seriated_groups() for x in khipu_sums_df.kfg_name.values]

fig = px.scatter(khipu_sums_df, 
                 x='num_seriated_groups', y='num_banded_groups', 
                 hover_name='kfg_name', hover_data=["num_banded_groups", "num_seriated_groups", "num_sum_groups"],
                 size="num_sum_groups", 
                 color='banded_color', color_continuous_scale=['#3c3fff', '#ff3030',],
                 labels={"num_sum_groups":"# of Group Group Sum Cords"},
                 title=f"<b>Group Group Sums by Banded/Seriated</b> - Blue=Banded, Red=Seriated, Size=#SumGroups",
                 width=944, height=944).update_coloraxes(showscale=False).show()

6. Conclusion:

  • This is a relationship that appears mostly on banded khipus
  • Even when we remove unequal length group group pairs, there still remains an interesting set of 66 relationships over 33 khipus.
  • The set of relationships range in sum size from 100 to 6000
  • Right group sums are usually 4 to 5 cords away from the left group sum counterpart.
  • Their distribution, in terms of distance, is similar in distribution to handedness of indexed pendant sums and subsidiary pendant sums.