def Syy(xydata): """Return Syy = n*sum(y**2) - sum(y)**2 from (x,y) data or y data alone. Returns Syy from either a single iterable or a pair of iterables. If given a single iterable argument, it must be either the (x,y) values, in which case the x values are ignored, or the y values alone: >>> Syy([(1, 2), (3, 4), (5, 8)]) 56.0 >>> Syy([2, 4, 8]) 56.0 In the two argument form, Syy(xdata, ydata), the first argument xdata is ignored except that the data is truncated at the shorter of the two arguments: >>> Syy([1, 3, 5], [2, 4, 8, 16, 32]) 56.0 """ # We expect (x,y) points, but if the caller passed a single iterable # ydata as argument, it gets mistaken as xdata with the y values all # set to None. (See the merge_xydata function.) We have to detect # that and swap the values around. try: first = next(xydata) except StopIteration: pass # Postpone dealing with this. else: if len(first) == 2 and first[1] is None: # Swap the elements around. first = (first[1], first[0]) xydata = ((x, y) for (y, x) in xydata) # Re-insert the first element back into the data stream. xydata = itertools.chain([first], xydata) n, ss = _sum_sq_deviations((y for (x, y) in xydata), None) return ss*n
def Sxx(xydata): """Return Sxx = n*sum(x**2) - sum(x)**2 from (x,y) data or x data alone. Returns Sxx from either a single iterable or a pair of iterables. If given a single iterable argument, it must be either the (x,y) values, in which case the y values are ignored, or the x values alone: >>> Sxx([(1, 2), (3, 4), (5, 8)]) 24.0 >>> Sxx([1, 3, 5]) 24.0 In the two argument form, Sxx(xdata, ydata), the second argument ydata is ignored except that the data is truncated at the shorter of the two arguments: >>> Sxx([1, 3, 5, 7, 9], [2, 4, 8]) 24.0 """ n, ss = _sum_sq_deviations((x for (x, y) in xydata), None) return ss*n